C#中C ++ DLL的直接内存访问

时间:2013-12-10 12:28:11

标签: c# c++ dll pinvoke

我已经搜索了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#,因为你可以在notime中获得非常简单的GUI。我正在研究的C#GUI工具是用于加载DLL的完整性测试数据。我根本没有深刻的C#。到目前为止我所尝试的并没有成功,我知道由于C#没有任何指针概念,可能没有解决这个问题的方法。我在Java中使用JNA加载DLL时发现的类似问题导致我不再使用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)

使用像普通字符串,整数,布尔值这样的东西就像魅力一样的代码。只是这些字符串数组一直在困扰我: - )

注意:我无法改变DLL的工作方式,因为我为老板写了这个,并且他在C ++和Delphi程序中都使用它很好。它运行良好,我们不会改变DLL本身的任何内容,因为它确实很好。

非常感谢任何帮助或澄清,非常感谢,问候

1 个答案:

答案 0 :(得分:1)

out string[] dataArray

char**参数的错误翻译。它应该是:

IntPtr[] dataArray

调用C#代码然后在调用函数之前分配数组。就像C ++代码一样。

IntPtr[] data = new IntPtr[__num_fields];
int retval = DLLTest.MyFunction(data, __row);

然后,您可以使用Marshal类访问内存到您的内容,以读取IntPtr指针后面的非托管内存。

调用约定看起来有点奇怪。如上所述,C ++函数是cdecl。正如汉斯所说,还必须有一些机制让DLL知道传入的数组有多长。