Problem in calling a C++ dll function from C#

不打扰是莪最后的温柔 提交于 2019-12-07 03:47:27

To add to what jachymko has said, also check the documentation for BitConverter - you need to be sure you are passing the key and data in the byte order you intended. Note - from your previous thread, I successfully encrypted data using the modified Blowfish.NET encryptor and got it to match the result of your C++ code.

Are you aware of the fact that you are initializing a temporary instance that is destroyed by the time the Initkey function returns? You should combine the whole thing in one function, or create the cBlowfish on the heap and return the pointer to the C# code (it can treat it as an opaque IntPtr).

Moreover, you don't need to use unsafe here. Just pass the UInt32[] directly.

Arrays in C and C++ are passed as pointers. Semantics for arrays in C# include an additional layer of indirection. Your C# program is (probably) passing the address of a variable that holds the address of the data.

I recently wrestled with passing an array of bytes from C# to a C function and had to marshal the data in both directions. It's not obvious to me that your code is doing that.

Better than an explanation, I'll provide a concrete example:

//extern "C" LIBEXIFWRAPPER_API void findEXIFtagValue( void * load, unsigned int tagID, char* buf, int bufLen );
[DllImport("libexif-wrapper.dll")]
unsafe public static extern IntPtr findEXIFtagValue([MarshalAs(UnmanagedType.SysUInt)]IntPtr load, int tagID, [MarshalAs(UnmanagedType.SysUInt)]IntPtr buf, int bufLen); 

This function accepts a pointer to opaque data, an int and a byte array in which it stores a text string.

The following snippet shows how the byte array is declared, passed to the C function and the results extracted:

const int tagBuffer = 1024;
IntPtr buf = Marshal.AllocHGlobal(tagBuffer);

findEXIFtagValue(loader, (int)ExifTag.EXIF_TAG_DATE_TIME, buf, tagBuffer);
string s = Marshal.PtrToStringAnsi(buf);

Note that the argument is marshaled in the prototype and marshaled again to retrieve the result.

None of this was particularly obvious to me. It seems that IntPtr is the C# equivalent of void* except I had to use a SysUInt to manage a (C) void*. The pointer to the byte array is marshaled in as SysUInt.

(from a C# noob)

HTH

May be you should try using ref for pointers, and out for functions that return data through an argument. Let me know if that works. Thanks.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!