Interface from a C DLL to .NET

此生再无相见时 提交于 2019-12-12 14:48:00

问题


I have a legacy DLL written in C that I'd like to call from a C# .NET application. The problem is that the DLL interface for the C DLL is fairly complicated. It's something like this:

__declspec(dllexport) void __stdcall ProcessChunk(
    void *p_prochdl,
    const BIG_INPUT_STRC *p_inparams,
    BIG_OUTPUT_STRC *p_outparams
);

The BIG_INPUT_STRC/BIG_OUTPUT_STRC contain all kinds of things... pointers to buffer arrays, enumerated parameters, integer parameters, etc. In short, they're complicated.

First question: Is there an easy way to get all of the structure information that is contained in the DLL header file into the C# class, or do you need to literally copy and paste everything to C# and re-define it? This seems redundant.

Related to that, what is the correct way to pass structs into the unmanaged DLL from C#?

Finally, is there an example of how to correctly pass buffer arrays from C# into the unmanaged DLL? Alternatively, how can I pass a two-dimensional array into the DLL?

Thanks, -Greg


回答1:


Its quite straight forward to do this soft of thing in C# using P/Invoke.

I belive you are going to have to define the data structures in C# manually.

I would reccomend you take a look at this MSDN article on the subject




回答2:


You'll need to extensively use .net marshalling. First you need to re-define C structs in your C# code, then make sure everything gets marshalle properly using the MarshalAs attribute.

If you need to pass a pointer-to-structure in C# back to the C function you can use the Marshal.StructToPtr function.

Buffer arrays, assuming they're defined as byte[] you can marshal using the following technique:

byte[] buffer = ...;
fixed(byte *pBuffer = buffer)
{
   // do something with the pBuffer
}

The fixed statement makes sure that the bufffer doesn't get moved in the memory by the garbage collector, making the pointer within the statement 'fixed' or 'pinned'.

As for the multi dimensional arrays, it depends on the underlying C implementation, you might for example work with a pointer to the array and adjust the position based on the number of dimension and the number of elements in each dimension like:

someValue = buffer[(elementsPerDimensions * x) + y];

From your description it already seems pretty complicated, have you considered making your library COM friendly?




回答3:


What a pill.

  1. I'd avoid trying to make the library COM friendly. That's more trouble than its worth.

  2. I'd build a second native library with functions designed to be P/INVOKED to build up the records for the first and call it.

Alternately, you could make a C++ native/managed library to handle the marshaling.



来源:https://stackoverflow.com/questions/494376/interface-from-a-c-dll-to-net

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