如何通过p/invoke传递字符串
本文关键字:字符串 invoke 何通过 | 更新日期: 2023-09-27 18:26:31
我需要通过p/invoke传递一个字符串,它只是一个文件名,类似于"desc.xml"。我不在乎它是std::string
还是char*
,或者可能是其他类型的(我可以转换为appropiate类型)。我应该如何申报签名?
在c#方面,我期待类似的东西:
[DllImport("Native.dll"), SuppressUnmanagedCodeSecurity]
public static extern void Initialize(/*TODO: how to pass string?*/);
在c++方面,我期待类似的东西:
__declspec(dllexport) void Initialize(char* fileName);
或CCD_ 3而不是CCD_ 4
__declspec(dllexport) void Initialize(std::string& fileName);
我希望它能这样使用:
Initialize("desc.xml");
问题是我应该如何准确地声明参数。
public static extern void Initialize(string filename);
还要向DllImport("Native.dll")
中添加一个CharSet,以匹配C++端的内容(CharSet.Ansi
表示char*
,CharSet.Unicode
表示wchar*
)。
假设您想要接收ANSI编码的文本,您应该像这样声明C++代码:
__declspec(dllexport) void Initialize(const char* fileName);
这将使用默认的__cdecl
调用约定。该文本将作为指向以null结尾的char
数组的指针传递。
在C#方面,你这样声明:
[DllImport("Native.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern void Initialize(string fileName);
没有必要指定字符集,因为默认值是`ANSI。如果你想明确(在我看来这不是一个坏主意),那么你可以这样写:
[DllImport("Native.dll", CallingConvention=CallingConvention.Cdecl,
CharSet=CharSet.Ansi)]
public static extern void Initialize(string fileName);
如果按原样编译C++代码,函数的名称将被破坏。您必须使用DllImport
属性的EntryPoint
参数来指定损坏的名称。作为替代方案,您可以将本机代码对函数的声明封装在extern "C"
块中,以抑制损坏。