从 C DLL 到 .NET 的接口

发布于 2024-07-13 03:03:19 字数 577 浏览 4 评论 0原文

我有一个用 C 编写的遗留 DLL,我想从 C# .NET 应用程序调用它。 问题是 C DLL 的 DLL 接口相当复杂。 它是这样的:

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

BIG_INPUT_STRC/BIG_OUTPUT_STRC 包含各种各样的东西...指向缓冲区数组的指针、枚举参数、整数参数等。总之,它们很复杂。

第一个问题:是否有一种简单的方法可以将 DLL 头文件中包含的所有结构信息获取到 C# 类中,或者您是否需要将所有内容逐字复制并粘贴到 C# 中并重新定义它? 这似乎是多余的。

与此相关,从 C# 将结构传递到非托管 DLL 的正确方法是什么?

最后,是否有一个示例说明如何将缓冲区数组从 C# 正确传递到非托管 DLL 中? 或者,如何将二维数组传递到 DLL 中?

谢谢, -格雷格

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小…楫夜泊 2024-07-20 03:03:19

使用 P/Invoke 在 C# 中执行此操作非常简单。

我相信您将必须手动定义 C# 中的数据结构。

我建议您查看这篇关于该主题的 MSDN 文章

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

不语却知心 2024-07-20 03:03:19

您需要广泛使用 .net 编组。 首先,您需要在 C# 代码中重新定义 C 结构,然后确保使用 MarshalAs 属性。

如果需要将 C# 中的结构指针传递回 C 函数,可以使用 Marshal.StructToPtr 函数。

缓冲区数组,假设它们被定义为 byte[],您可以使用以下技术进行编组:

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

fixed 语句确保缓冲区不会被垃圾收集器移动到内存中,从而使语句中的指针“固定”或“固定”。

至于多维数组,它取决于底层 C 实现,例如,您可以使用指向数组的指针,并根据维度数和每个维度中的元素数调整位置,例如:

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

从您的描述来看看起来已经相当复杂了,你有没有考虑过让你的库变得 COM 友好?

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?

躲猫猫 2024-07-20 03:03:19

多么好的药丸啊。

  1. 我会避免尝试使库对 COM 友好。 这带来的麻烦多于其价值。

  2. 我将构建第二个本机库,其中包含设计为 P/INVOKED 的函数,以构建第一个库的记录并调用它。

或者,您可以创建一个 C++ 本机/托管库来处理封送处理。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文