从C#调用Delphi DLL函数

从C#调用Delphi DLL函数

问题描述:

这是Delphi函数的头文件:

this is the Delphi function header:

function CryptStr(str, Key : pchar; DecryptStr : boolean) : pchar; stdcall;


如何从C#调用此函数.它实际上位于一个名为Crypto.dll的DLL中.

请指导
谢谢


how to call this function from C#. it's actually inside a DLL named Crypto.dll

please guide
thanks

假定PCharPAnsiChar:

[DllImport("Crypto.dll")]
static extern IntPtr CryptStr(string str, string Key, bool DecryptStr);

然后这样称呼它:

IntPtr retvalPtr = CryptStr(str, Key, DecryptStr);
string retval = Marshal.PtrToStringAnsi(retvalPtr);

我希望您还需要调用DLL导出的函数,以释放CryptStr返回的指针后面的内存.您确实导出了我信任的这样的功能吗?

And I expect you'll also need to call the function that the DLL exports that frees the memory behind the pointer that CryptStr returned. You did export such a function I trust?

如果PCharPWideChar,则为:

[DllImport("Crypto.dll", CharSet = CharSet.Unicode)]
static extern IntPtr CryptStr(string str, string Key, bool DecryptStr);

然后这样称呼它:

IntPtr retvalPtr = CryptStr(str, Key, DecryptStr);
string retval = Marshal.PtrToStringUni(retvalPtr);


最后,如果您想变得非常可爱,则可以安排Delphi代码使用CoTaskMemAlloc从COM堆中分配返回值字符串.如果这样做,则可以避免手动编组,而让p/invoke编组执行解除分配.看起来像这样.


Finally, if you wanted to be really cute, you could arrange for the Delphi code to allocate the return value string from the COM heap using CoTaskMemAlloc. If you did that, then you could avoid the manual marshalling, and let the p/invoke marshaller perform the deallocation. That would look like this.

[DllImport("Crypto.dll", CharSet = CharSet.Unicode)]
static extern string CryptStr(string str, string Key, bool DecryptStr);

然后这样称呼它:

string retval = CryptStr(str, Key, DecryptStr);

现在应该很清楚如何编码ANSI变体,因此我将省略它.

It should be obvious now how to code the ANSI variant and so I will omit it.

当您声明返回值为string的p/invoke时,编组器将假定本机代码返回指向以空值终止的字符数组的指针.并且还假定内存是从COM堆中分配的,并调用CoTaskMemFree来取消分配内存.因此,这样做避免了需要从DLL中导出单独的deallocator函数.

When you declare a p/invoke with a string return value, the marshaller assumes that the native code returns a pointer to a null-terminated array of characters. And it also assumes that the memory was allocated off the COM heap, and makes a call to CoTaskMemFree to deallocate the memory. So, doing it this way avoids the need for a separate deallocator function to be exported from the DLL.