How to initialize sbyte* in c# - c#

I am building a c# application, in my application, I load a c++/cli dll, and calling its function.
I have declare a value class in my c++/cli class.
public value class S_OpenParam {
public :
int iPort;
char* szIpAddress;
int iBaudRate;
};
Then , I am trying to initialize my S_OpenParam in my c# application.
I am facing problem on initialize the char* szIpAddress
myObj.S_OpenParam sParam;
sParam.iBaudRate = 0;
sParam.iPort = 0;
When I try to assign a value to it:
sParam.szIpAddress = "127.0.0.1";
It shows the type is sbyte*
Do you know how to initialize it ?

Since you are in a C++/CLI dll, why don't you use String^ instead of char*, so that you will be able to update it from c# without problems ?
public value class S_OpenParam {
public :
int iPort;
String^ szIpAddress; <-- String^ instead of char*
int iBaudRate;
};

Related

Marshaling C# struct to C++ dll - different values

I have a DLL written in C++ and I am trying to call a function that expects a struct from my C# project.
Here's its declaration
int _stdcall InitialiseMotors(int i_nBoard, Array_Of_Structures moveParameters)
And here is the declaration of the struct
typedef struct MoveMotorSolenoidParametersTag
{
bool SetDirectionForMotor;
int SetNumberOfStepsForMotor;
bool TurnSolenoidsON_OFF;
} MoveMotorSolenoidParameters;
The corresponding call in C#:
[DllImport(DllBeingUsed)]
private static extern int InitialiseMotors(int i_nBoard,
DllDatatypes.MoveMotorSolenoidParameters moveMotorSolenoidParameters);
And the definition of my structure:
[StructLayout(LayoutKind.Sequential)]
public struct MoveMotorSolenoidParameters
{
public bool SetDirectionForMotor;
public int SetNumberOfStepsForMotor;
public bool TurnSolenoidsON_OFF;
public MoveMotorSolenoidParameters(bool setDirectionForMotor = true,
int setNumberofStepsForMotor = 10,
bool turnSolenoidsON_OFF = true )
{
SetDirectionForMotor = setDirectionForMotor;
SetNumberOfStepsForMotor = setNumberofStepsForMotor;
TurnSolenoidsON_OFF = turnSolenoidsON_OFF;
}
}
Even though I am passing the values true, 10 and true, my DLL seems to be getting different values. true, 167772160 and false. I can see these values by putting a breakpoint on the DLL. I checked the values before the DLL function is called and they are correct. So I am assuming something is happening during the marshalling.
QuickWatch of C++ struct
Any ideas why this is happening?

Calling C++ Code with a struct from C#

I was given a third party library that wraps unmanaged C++ code into a C# api, one of the functions has a parameter that appears to be a struct from the native global namespace how do we create an instance of that struct in C#?
This is the c++ Struct:
struct GroupInfo
{
int cMembers; // Current # of members in the group.
char saMembers[cMaxMembers][cMaxLoginID + 1]; // Members themselves.
};
When we try to declare an instance of it in C# the compiler says global::GroupInfo is not available due to its protection level.
c++ signature
int QueryGroup(char* sGroupName,
GroupInfo& gi);
C# signature
VMIManaged.QueryGroup(sbyte*, GroupInfo*)
I have a class called group info
class GroupInfo
{
public int cMembers;
public sbyte[,] saMembers;
}
and when i try to implement that using this code i get a cannot convert error
GroupInfo gi = new GroupInfo();
unsafe
{
sbyte* grpName;
fixed (byte* p = groupNameBytes)
{
grpName = (sbyte*)p;
}
return vmi.QueryGroup(grpName, gi); // cannot convert from class GroupInfo to GroupInfo*
}
You are most likely getting the error because of the default protection level of the default constructor in C# for your GroupData class. If it is defined in a different file from the file in which you are trying to use it, defining it like this should work:
class GroupInfo
{
public GroupInfo() {}
public int cMembers;
public sbyte saMembers[cMaxMembers][cMaxLoginID + 1];
};

how to create binding for an extern declaration

I'm trying to create a binding for an iOS library.
When creating a native app with this library, it requires to include a .h header file which declares a global ApplicationKey variable like this:
extern const unsigned char ApplicationKey[];
and you are supposed to implement it
const unsigned char ApplicationKey[] = {0x11, ... };
Now, when creating the Xamarin binding for this library, the header file is mapped by Objective Sharpie to
partial interface Constants
{
// extern const unsigned char [] ApplicationKey;
[Field ("ApplicationKey")]
byte[] ApplicationKey { get; }
}
How to change it to be able to set ApplicationKey from C# code?
Your ApiDefination.cs file should be like this
[BaseType (typeof(NSObject))]
public partial interface Constants
{
[Export ("ApplicationKey")]
TypeOfProperyInNativeCode ApplicationKey { get; set; }
}
in order to access this property create instance of Constant Class of binding project and access like this
Binding.Constant cons= new Binding.Constant();
cons.ApplicationKey =value;
For better understanding you can follow this link http://developer.xamarin.com/guides/ios/advanced_topics/binding_objective-c/Walkthrough_Binding_objective-c_library/

How to keep C struct references to a C# struct with Marshal or GCHandle?

I found several questions on this topic but nothing, which fits my exact problem. I'm having structs in a C DLL, for example like this one here:
extern "C"
{
struct CStruct
{
int alpha;
double beta;
};
}
CSharpStruct has the same structure as its C friend, like this:
public struct CSharpStruct
{
public int alpha;
public double beta;
}
and want to deliver the data by reference to a c# program.
I created a method in the C DLL which is able to return
a pointer to the struct like this one here: (test data)
const EXPORT_API CStruct* GetStruct()
{
CStruct1.alpha = 21;
CStruct1.beta = 23.141;
return &CStruct1;
}
and I am able to access the data in c# in this way:
[DllImport("ASimplePlugin")]
private static extern IntPtr GetStruct();
//...
IntPtr cStruct = GetStruct();
CSharpStruct test = (CSharpStruct) Marshal.PtrToStructure(cStruct, typeof(CSharpStruct));
After that I can access the data from C, but Marshal.PtrToStructure
copies them from the IntPtr reference into the C# struct by Value.
What I want to achieve is to have a direct reference to the c values
in the c# struct so that changing it in c# changes the values in c.
How is this possible?

public struct in managed c++ dll cannot be seen from c#

I have a c# application. It references a c++-cli dll. In the namespace of the c++ dll a public struct is declared:
namespace Wrapper {
public struct maxs
{
public:
char Name[255];
int num;
};
etc
There is a function in the c++ dll which returns a pointer to a pointer to the struct.
Wrapper::Maxs** Wrapper::Class1::CallMax();
The C# application references the c++ dll and declares an instance of the struct (unsafe code)
Wrapper.Class1 oMax = new Wrapper.Class1()
Wrapper.Maxs** maxs;
maxs= oMax.CallMax();
int num = oMax.m_num;
Then I try to access the fields of maxs like so:
for(int i = 0; i < num; ++i)
{
name = maxs[i]->name;
}
However, that 'name' field is not visible in the c# intellisense and doesn't compile.
Interestingly I went to see the definition of the struct in the c++ metadata and the struct is blank..
using System;
using System.Runtime.CompilerServices;
namespaceWrapper
{
[CLSCompliant(false)]
[NativeCppClass]
[UnsafeValueType]
public struct Maxs
{
}
}
Is that normal?
So the question is: Why can c# not see the fields of the public struct Maxs? And why is the metadata info show a blank struct?
thanks.
This is the correct answer AFAIK:
Because it is not a managed struct. You'll need to declare it as public value struct instead. – Hans Passant Mar 24 at 2:33

Categories

Resources