【问题标题】:Marshalling static const char* from C++ to C#将静态 const char* 从 C++ 编组到 C#
【发布时间】:2014-02-04 15:49:35
【问题描述】:

我有一段代码,我想知道它是否正确:

你好.cpp

static const char _someGlovalVar[] = "my persistant gloval variable";


const char* DLLInterfaceGetName()
{
    return _someGlovalVar;  
}

你好.h

DLL_EXPORT const char* DLLInterfaceGetName();

你好.cs

[DllImport("hello.dll", EntryPoint = "DLLInterfaceGetName", CharSet = CharSet.Ansi)]
public static extern string DLLInterfaceGetName();

这对吗?

【问题讨论】:

  • DllImport and char* 的可能重复项
  • 看起来是正确的,但 id 参数应该添加到您的 C++ DLLInterfaceGetName 声明和定义中,或者从您的 C# 声明中删除。
  • 我不认为它与stackoverflow.com/questions/2568436/dllimport-and-char 重复。在此链接上还有另一种解决方案。我现在想知道这个解决方案是否正确以及为什么。

标签: c# c++ static global-variables marshalling


【解决方案1】:

将返回值更改为 IntPtr 而不是字符串。

[DllImport("hello.dll", EntryPoint = "DLLInterfaceGetName", CharSet = CharSet.Ansi)]
public static extern IntPtr DLLInterfaceGetName();

然后,当您在 C# 代码中调用它时,将指针编组为 C# 字符串:

IntPtr cstr = DLLInterfaceGetName();
String str = Marshal.PtrToStringAnsi(cstr);

另外,请仔细检查您在 DLLImport 上使用了正确的调用约定。我遇到了一个问题,因为它默认使用 StdCall,而我实际上想要 Cdecl。

【讨论】:

  • 实际上,我的回答并没有真正回答你的问题——它只是展示了另一种方法。我确实找到了这个:msdn.microsoft.com/en-us/magazine/cc164193.aspx 那里有一些关于封送返回值的信息,尤其是字符串。这似乎表明您拥有的代码应该按照您希望的方式在幕后工作,方法是创建一个字符串对象并将 char* 复制到其中,然后再将其交给您。
【解决方案2】:

有效吗?在这种情况下,我认为您不必关心其他任何事情:)

虽然就个人而言,我有点担心如何处理。静态 const char[] 指针可能在代码部分,不是吗?希望 .NET 编组器将字符串中的数据复制到它自己的字符串中。我也不确定 CPP 方面是如何处理这个问题的——不同的编译器是否有可能产生截然不同的输出?

另外,你不应该在字符串末尾加上\0 吗?调用者如何知道仅char[] 的字符串有多长?我认为如果它不适合你,这就是原因。

【讨论】:

  • 是的,它似乎正在工作,但我不确定它在理论上是否正确。库中发布模式存在一些访问冲突,但我仍然没有找到原因。我只有一个怀疑。
猜你喜欢
  • 2020-08-01
  • 1970-01-01
  • 2013-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-26
  • 2013-01-25
  • 1970-01-01
相关资源
最近更新 更多