-2

我需要通过 p/invoke 传递一个字符串,它只是一个文件名,类似于“desc.xml”。我不在乎它是否会std::stringchar*可能是其他东西(我可以转换为适当的类型)。我应该如何声明签名?

在 c# 方面,我期望这样的东西:

    [DllImport("Native.dll"), SuppressUnmanagedCodeSecurity]
    public static extern void Initialize(/*TODO: how to pass string?*/);

在 c++ 方面,我希望是这样的:

__declspec(dllexport) void Initialize(char* fileName);

std::string代替char*

__declspec(dllexport) void Initialize(std::string& fileName);

我希望它可以这样使用:

Initialize("desc.xml");

问题是我应该如何声明参数。

4

2 回答 2

3
public static extern void Initialize(string filename);

还要向您添加一个CharSetDllImport("Native.dll")以匹配您在 C++ 方面的内容(CharSet.Ansifor char*CharSet.Unicodefor wchar*)。

于 2013-08-05T12:26:42.640 回答
2

假设你想接收 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++ 代码,则函数的名称将被破坏。您必须使用属性的EntryPoint参数DllImport来指定损坏的名称。作为替代方案,您可以将本机代码的函数声明包装在一个extern "C"块中以抑制重整。

于 2013-08-05T13:41:44.563 回答