【问题标题】:Why does passing a string from C# to a C++ dll get NULL?为什么将字符串从 C# 传递到 C++ dll 得到 NULL?
【发布时间】:2018-07-17 16:51:35
【问题描述】:

我正在尝试将 C# 可执行文件连接到 C++ dll。 dll的一个方法接收一个const char*和一个int*(第一个指定输入值,第二个指定返回值的地址):

extern "C" __declspec(dllexport)
  int setVal(long handle, const char* ptrVal, int* ptrRet);

这个函数做的第一件事是检查ptrVal是否为空,如果是则返回-1。

另一方面,C# 代码调用 dll 如下:

[DllImport(dllName,
           EntryPoint = "setVal",
           ExactSpelling = true,
           CallingConvention = CallingConvention.Cdecl,
           CharSet = CharSet.Ansi)]
public static extern int setVal(long handle,
                                [MarshalAs(UnmanagedType.LPStr)] string str,
                                ref int ptrRes);

在主函数中,我有

long handle = 0;
int result = 0;
int res = 0;
string str = "Hello World!";
result = setVal(handle, str, ref res);

调用这个函数时,我总是在C端收到一个空指针,这使得结果等于-1。我在声明包装函数时尝试了不同的方法,但没有成功:

public static extern int setVal(long handle, 
                                [MarshalAs(UnmanagedType.LPStr)] [In] string str,
                                [Out] int ptrRes);
public static unsafe extern int setVal(long handle,
                                       [MarshalAs(UnmanagedType.LPStr)] string str,
                                       ref int ptrRes);
public static extern int setVal(long handle, 
                                StringBuilder sb,
                                ref int ptrRes); // also the unsafe version
public static extern int setVal(long handle,
                                byte[] value,
                                ref int ptrRes); // also the unsafe version

我正在使用 Visual Studio 2017 和 .NET 框架 4.6.1。

为什么我总是收到 NULL 作为 dll 函数的第二个参数 (const char*)?

【问题讨论】:

标签: c# c++ visual-studio-2017


【解决方案1】:

我做了一点谷歌,所以这将是未经测试的代码,但我可以看到这是你没有尝试过的东西

像这样声明外部

[DllImport(dllName, EntryPoint = "setVal", ExactSpelling = true, CallingConvention, CallingConvention.Cdecl,CharSet = CharSet.Ansi)]
public static extern int setVal(int handle, StringBuilder sb, ref int ptrRes);

并像这样使用它

int handle = 0;
int result = 0;
int res = 0;
StringBuilder sb = new StringBuilder("Hello World");
result = setVal(handle, sb, ref res);

【讨论】:

  • 感谢 xanatos 和你们,我终于成功了!键是 int 而不是 long!
【解决方案2】:

在 Windows 上,C/C++ 中的 long handle 在 C# 中是 32 位和 64 位的 int handle。您可以通过在 C/C++ 中执行 sizeof(long) 来检查它。 Windows 是LLP64

【讨论】:

  • 非常感谢!使用 int 是关键!
猜你喜欢
  • 2012-02-12
  • 2014-02-24
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 2019-06-01
  • 1970-01-01
相关资源
最近更新 更多