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

标签 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#,因为您可以立即获得非常简单的 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/

相关文章:

c# - 以编程方式从资源字典中添加删除项目

c++ - 无法在 VB.NET 中使用带有来自 Visual C++ DLL 的指针参数的函数

c++ - gcc - 如何在结构定义中组合 __attribute__((dllexport)) 和 [[nodiscard]]?

c# - VPF 中的视频捕获

c# - 按时间顺序获取最新 x 条目的最佳方式

C# 对象数组是否存储所述对象的指针?

c++ - REGSVR32: 模块 "xxxxx.dll"加载失败...找不到相关程序集

c++ - 我们可以在没有 MSTest 的情况下在 VS2012 或 VS2010 中获得原生 C++ 代码覆盖率吗?

c++ - 在 MATLAB 中迭代坐标矩阵的最佳方法?

c++ - 如何将齐次 fusion::vector 转换为 (std/boost)::数组