我在 stackoverflow 上搜索了这个问题,但没有找到确切的问题。特别是,当 C# 端管理内存而不是其他方式时,我发现了大量关于检索 C++ 字符串引用 (char**) 的问题。
情况如下。我有一个我自己写的 DLL(写在 VC++ 2012 上)。它从文件中加载和解析数据,然后允许任何使用 DLL 的人以多种方式访问此数据(出于性能原因,通过实际的直接内存访问)。任何使用此 DLL 的 C++ 程序显然都没有问题。 C# 看起来确实...
一点背景:
DLL 提供接受 char**(char* 数组)参数的导出函数,其元素被设置到 DLL 中的内存位置,然后在调用后由 DLL 的用户进一步处理。
一个示例可能如下所示(示例性实现):
int myFunction(char* dataArray[], int row)
{
for (int i= 0; i < _something; ++i)
{
dataArray[i] = _some_char_ptr
}
}
这就是被调用者的实现在 C++ 中的样子:
char** data = new char*[__num_fields];
myFunction(data, __some_row);
for (int i= 0; i < __something; ++i)
{
cout << data[i] << endl;
}
特殊 - 因此与我发现的所有问题不同 - 关于这一点,被调用方分配了一个 char* 列表,该列表在调用指向由 DLL 本身分配的内存位置之后。
现在,我必须说,我只使用 C#,因为您可以立即获得非常简单的 GUI。我正在使用的 C# GUI 工具用于完整性测试 DLL 加载的数据。我对 C# 一点都不了解。到目前为止,我所尝试的完全没有成功,而且我知道由于 C# 没有任何类型的指针概念,因此可能没有解决此问题的方法。我在使用 JNA 加载 DLL 时在 Java 中发现了类似的问题,这导致我不再将 Java 用于此类测试目的。
现在我尝试了一些 C# 的东西,包括。上下文:
public static class DLLTest
{
// delegate object for the function:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int MyFunction_Type(out string[] dataArray, int row);
public static MyFunction_Type MyFunction { get; private set; }
public static void Load()
{
IntPtr dllAddress = DllUtilities.LoadLibrary(@"__dll_path");
IntPtr procAddress = DllUtilities.GetProcAddress(dllAddress, "myFunction");
MyFunction = (MyFunction_Type)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(MyFunction_Type));
}
}
然后我像这样调用函数:
string[] data = new string[__num_fields];
DLLTest.MyFunction(out data, __row)
类似于此的代码使用普通字符串、整数、 bool 值之类的东西,无论什么都像魅力一样。只是这些字符串数组一直困扰着我:-)
注意:我无法更改 DLL 的工作方式,因为这是我为我的老板编写的,他在 C++ 和 Delphi 程序中都很好地使用了它。它运行良好,我们不打算更改 DLL 本身的任何内容,因为它确实很好。
非常感谢任何帮助或澄清,非常感谢,问候
最佳答案
out string[] dataArray
是 char**
参数的错误翻译。应该是:
IntPtr[] dataArray
调用 C# 代码然后在调用函数之前分配数组。正如 C++ 代码所做的那样。
IntPtr[] data = new IntPtr[__num_fields];
int retval = DLLTest.MyFunction(data, __row);
然后,您可以使用 Marshal
类访问内存,以读取 IntPtr
指针后面的非托管内存。
调用约定看起来有点奇怪。如所写,C++ 函数是 cdecl
。正如 Hans 所说,还必须有某种机制让 DLL 知道传入的数组有多长。
关于c# - C#中C++ DLL的直接内存访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20494552/