C# C+的直接内存访问+;C语言中的动态链接库#

C# C+的直接内存访问+;C语言中的动态链接库#,c#,c++,dll,pinvoke,C#,C++,Dll,Pinvoke,我已搜索stackoverflow以查找此问题,但没有找到确切的问题。特别是,当C语言管理内存但不是其他方法时,我发现了大量关于C++ C++字符串引用(char **)的问题。 情况如下。我有一个DLL(写在VC++2012上),是我自己写的。它从文件中加载和解析数据,然后允许任何使用DLL的人以多种方式访问此数据(出于性能原因,通过实际的直接内存访问)。在C++中使用这个DLL的任何程序显然没有问题。C#看起来是这样的 一点背景: DLL提供的导出函数接受char**(char*数组)参数,

我已搜索stackoverflow以查找此问题,但没有找到确切的问题。特别是,当C语言管理内存但不是其他方法时,我发现了大量关于C++ C++字符串引用(char **)的问题。 情况如下。我有一个DLL(写在VC++2012上),是我自己写的。它从文件中加载和解析数据,然后允许任何使用DLL的人以多种方式访问此数据(出于性能原因,通过实际的直接内存访问)。在C++中使用这个DLL的任何程序显然没有问题。C#看起来是这样的

一点背景:

DLL提供的导出函数接受char**(char*数组)参数,这些参数的元素被设置为DLL中的内存位置,然后在调用后由DLL的用户进一步处理

示例可能如下所示(示例实现):

然后我像这样调用函数:

string[] data = new string[__num_fields];
DLLTest.MyFunction(out data, __row)
类似的代码使用普通字符串、整数、布尔值等类似的东西。只是这些字符串数组一直困扰着我:-)

注:我不能改变DLL的工作方式,因为我为我的老板写了这个,他在C++和Delphi程序中都很好用。它的性能很好,我们不打算改变DLL本身的任何东西,因为它确实很好

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

out string[] dataArray
char**
参数的错误翻译。应该是:

IntPtr[] dataArray
然后,调用C#代码在调用函数之前分配数组。正如C++代码所做的那样。

IntPtr[] data = new IntPtr[__num_fields];
int retval = DLLTest.MyFunction(data, __row);
然后,您可以使用
封送
类访问内容的内存,以读取
IntPtr
指针后面的非托管内存


电话会议看起来有点奇怪。C++编写的函数是代码> CDECL < /C>。正如Hans所说,DLL还必须有某种机制来知道传入数组的长度。

调用convention.StdCall
为什么?这是来自internet的复制粘贴行。我使用“extern”C“导出DLL的函数,它利用stdcall调用约定,从而禁用名称篡改。这条精确的线也代表所有其他的DLL函数。<代码>外部“C”< /C> >禁止C++的修改。它不设置调用约定。在x64 STD和C上是相同的约定,但是在x86上它们不同,所以C ^必须匹配C++声明。这是非常危险的代码,C++代码可以很容易地破坏GC堆,因为它不知道经过的数组到底有多长。它需要知道_unum_u字段才能安全地执行它,但它不知道。还有一个严重的内存管理问题,这些字符串需要再次释放,而C代码无法做到这一点。不要这样做。DLL中的每个导出函数都有以下前缀:extern“C”\uuu declspec(dllexport)。我把它放在这里不是为了可读性。@poljpocket没关系。除非您显式地编写
\uu stdcall
,否则函数仍然是
\uu cdecl
。您正在询问DLL如何向其内存提供指针。这意味着DLL必须以
IntPtr
的形式为您提供这些指针。从非托管内存读取的函数可以在
封送
类中找到。顺便说一下,您可能会考虑使用Delphi VCL用于GUI,因为您已经有了从Delphi访问DLL的代码。与C#相比,使用指针可能更容易,并且在GUI构建中非常有效。另一方面,如果你不喜欢Pascal,那么它有多好可能无关紧要!!完美的谢谢!我刚刚成功地从DLL中获取了我的列表!
out string[] dataArray
IntPtr[] dataArray
IntPtr[] data = new IntPtr[__num_fields];
int retval = DLLTest.MyFunction(data, __row);