【问题标题】:c# DLLImport calling c++ method with char* as parameterc#DLLImport以char*为参数调用c++方法
【发布时间】:2015-02-13 10:31:04
【问题描述】:

我通过以下方法获得了一个外部 DLL (c++):

 void _stdcall Set_Config(char* config)

我使用以下c#代码调用该方法:

[DllImport(DllName,CharSet=CharSet.Auto)]
    public static extern void Set_Config(String config);

但是当我执行我的 c# 代码时,我得到了访问冲突异常或 System.Runtime.InteropServices.SEHException。 (我的dll是32位的,我的c#编译器编译成32位)

我也尝试用 Stringbuilder 替换 String config,但结果相同。

谁能帮我解决这个问题或给出一些示例代码我必须如何调用 c++ 方法?

【问题讨论】:

  • 你试过 CharSet.Ansi 和 CharSet.Unicode 吗?

标签: c# pinvoke dllimport


【解决方案1】:

CharSet.Auto 将编码为 UTF-16。但是您的函数接受char*,因此文本被编码为 8 位文本,大概是 ANSI。

[DllImport(DllName, CharSet = CharSet.Ansi)]
public static extern void Set_Config(string config);

调用函数很简单。

我假设字符串被传递到函数中。另一方面,奇怪的是参数是char* 而不是const char*。要么开发人员不知道如何使用const,要么该函数确实将数据发送回调用者。

如果数据以另一种方式流动,那么您就有麻烦了。您需要传递StringBuilder,但您无法告诉DLL 有多大的缓冲区可用。如果数据以另一种方式流动,则代码如下所示:

[DllImport(DllName, CharSet = CharSet.Ansi)]
public static extern void Set_Config(StringBuilder config);

这样调用函数:

StringBuilder config = new StringBuilder(256); // cross your fingers
Set_Config(config);

无论哪种方式,您都需要更清楚地了解这个函数实际上在做什么。在您知道是传入数据还是接收数据之前,您不能希望调用此函数。

【讨论】:

  • 感谢您的回答。该方法只是设置一些没有返回值的配置。当我尝试使用您的解决方案时,我仍然得到 System.AccessViolationException ;(
  • 你知道数据的流动方式吗?
  • 数据从我的 c# 应用程序流入 dll 方法
  • 好的,那么第一个摘录就是你所需要的
  • 非常感谢您的解释。当我理解正确时,当我尝试调用该方法时,我的 c# 参数转换为 8 位字符,对吗?我仍然得到 System.AccessViolationException Attempted to read or write protected memory。这通常表明其他内存已损坏
【解决方案2】:

您必须传递一个IntPtr,它是指向您的字符串的原始指针。 (根据我的记忆,Marshal.StringToBSTR

public static extern void Set_Config(IntPtr config);

【讨论】:

  • 您为什么需要这样做? string 编组为 C 字符串。 BSTR 不在这里。问题中没有BSTR
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-08
  • 1970-01-01
相关资源
最近更新 更多