- 在我的c代码中,我有一个结构,其中包含非托管dll中的许多未知大小的数组(c代码)
- 我需要将这个结构的一个实例的数据封送到c#,我稍后会将其发送回非托管的c代码
- 一旦到达csharp,我就不需要操纵这些数据,只需保留它/存储一段时间(因此它可以保留在字节数组中)。
- 我不想使用关键字'unsafe',因为它是一个大项目,这只是一小部分,我不想像那样编译。
我尝试将其编组为lpArray并且一切看起来都很好但是当我回到csharp后查看内容时,它总是空的。这种类型的编组样式对我来说适用于各种类型的动态数组,但不适用于结构体。
在网上搜索空白和比我自己更复杂的场景,但是如果有人看到这样的链接,请在这里发布我会非常好!
感谢。
- 这里更新或多或少是我的代码结构:
C#:
[DllImport("mydll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern int W_Thread_Connect_NET(
[MarshalAs(UnmanagedType.LPStr, SizeConst = 100)] string IPAddress,
int DevicePort,
[MarshalAs(UnmanagedType.LPArray)] byte[] connectionHandle
);
//and call it like this, with an empty struc to be populated by c (can this be done? it is comming back without the data):
byte[] myStrucParam= new byte[100];
int result = W_Thread_Connect_NET(myStrucParam, myParam1, myParam2, ...);
C:
typedef struct myStructDef{
char* myArray1,
char* myArray2,
int myInt1,
...
} mystrucObj, *pMystrucObj;
//method that i am wanting to marshal the struct as a paramter here..
MYDLL_DLLIMPORT int APIENTRY W_Thread_Connect_NET(pMystrucObj strucReturn_handle, char * IPAddress, int DevicePort, ...)
{
//(omitted)
}
答案 0 :(得分:2)
你说C#代码不需要操作结构。这使得它成为一个非常简单的问题。您可以将结构指针视为不透明指针,即IntPtr
。
首先,在本机代码中添加一个新函数:
pMystrucObj CreateStruct(void)
{
pMystrucObj res = malloc(sizeof(*res));
return res;
}
然后在您的C#代码中,您可以这样称呼它:
[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern IntPtr CreateStruct();
现在声明W_Thread_Connect_NET
就像这样:
[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int W_Thread_Connect_NET(
IntPtr theStructPtr,
string IPAddress,
int DevicePort,
....
);
并称之为:
IntPtr theStructPtr = CreateStruct();
int res = W_Thread_Connect_NET(theStructPtr, IPAddress, DevicePort, ...);
当然,你需要添加另一个名为DestroyStruct
的函数,以便在完成后释放结构的内存。