C# - 马歇尔&将void指针传递给C函数调用C函数

时间:2017-11-17 22:26:12

标签: c# c pointers marshalling void-pointers

我正在为基于C的库实现c#.net包装器。目前,通过传递一个void指针来处理函数,它将设置值。

注意: void指针可以采用不同的数据类型,具体取决于Enum。

  

目标:传递void指针并设置值

我检查了很多解决方案,最后来到了以下状态:

C-dll功能:

int function_call(enum a, void * var);

C函数调用代码:

char name[255];
name = "asd";
function_call(enum a, &name);

C#包装器代码:

[DllImport("mylibrary.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int function_call(enum a, IntPtr var);

C#函数调用代码:

IntPtr name;
string val = "asd";
name = Marshal.StringToHGolbalUni(val);
int ret = function_call(Enum_type, name);
  

通过此方法,它仅从输入a设置第一个字符asd

我已经检查了“重复”问题,但没有解决问题:

c++ - What is void* in C#

How to declare void pointer in C#

void* in C#

2 个答案:

答案 0 :(得分:2)

我会将您的void *视为char *并使用

[MarshalAs(UnmanagedType.LPStr)] StringBuilder var

而不是IntPtr

您应该发现它按预期工作,但要注意C函数所期望的char数组的大小。在调用C函数之前,可能是StringBuilder变量声明中的显式大小:

StringBuilder newvar= new StringBuilder(512);

解释使用StringBuilder而不是String或IntPtr的情况的良好链接解释here - 感谢Amy链接

答案 1 :(得分:0)

问题已通过以下方式解决:

[DllImport("mylibrary.dll", CharSet = CharSet.Ansi,  CallingConvention = CallingConvention.Cdecl)]

name = Marshal.StringToHGolbalAnsi(val);

在客户端:

IntPtr nameptr;
string name = "asd";
nameptr= Marshal.StringToHGlobalAnsi(name);