【问题标题】:Consume Native DLL In C#在 C# 中使用本机 DLL
【发布时间】:2012-02-23 19:57:19
【问题描述】:

我们聘请了一名 C 程序员来开发用于 .NET 应用程序的本机组件。我们就概念 API 达成了一致。我会将他的方法传递给两个数组,然后他将返回一个数组。我今天拿到了代码。这是头文件。真实姓名被掩盖:

__declspec(dllexport) int NativeMethod(
    struct params * config,
    int c_input_a_rows, 
    struct input_a_row *input_a_rows,
    int c_input_b_rows, 
    struct input_b_row *input_b_rows,
    int c_count, 
    int *p_c_output_rows, 
    struct output_row * output_rows);

struct params
{
    int a;
    int b;
    int c;
    double d;
    double e;
    int f;
    int g;
    char h[1000];
};

struct input_a_row
{
    int a;
    int b;
    double c;
};

struct input_b_row
{
    int a;
    int b;
    int c;
    int d;
    int e;
    double f;
    double g;
};

struct output_row
{
    int a;
    int b;
    int c;
    int d;
    int e;
    int f;
    int g;
    double h;
    double i;
    double j;
};

据此,我使用P/Invoke Interop Assistant 生成了.NET 代码。我无法通过打开 DLL 来让它工作。它抱怨该文件没有程序集清单。所以我将头文件插入 SigImpl Translate Snipped 并得到了这个:

[DllImport("the.dll", EntryPoint="NativeMethod")]
public static extern int NativeMethod(
    ref params config,
    int c_input_a_rows, 
    ref input_a_row input_a_rows,
    int c_input_b_rows, 
    ref input_b_row input_b_rows,
    int c_count, 
    ref int p_c_output_rows, 
    ref output_row output_rows);

它还按预期创建所有结构。每个都有一个类属性:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

两个问题。此代码是否正确生成?其次,我该如何使用它?签名没有数组。我知道我可能需要以某种方式使用指针,但是如何?我不希望你为我解决这个问题,但是你能指出一些方法来理解如何在不参加低原生编程课程的情况下解决这个问题吗?谢谢!

【问题讨论】:

    标签: .net c dll native dllimport


    【解决方案1】:

    好的,在我发布这个问题后,我又开始偷偷摸摸了。我尝试的第一件事奏效了!

        private static extern int NativeMethod(
            params config,
            input_a_row[] input_a_rows,
            input_b_row[] input_b_rows,
            int count,
            ref output_row[] output_rows);
    

    我还有一件事要做。我收到一个错误,即找不到入口点。我通过使用 DUMPBIN(来自 VS 控制台)解决了这个问题,发现导出实际上被命名为 ?NativeMethod@@YAHPAUconfig@@HPAUinput_row_a@@HPAUinput_row_b@@HPAHPAUoutput_row@@@Z。这有多脆弱?!

    【讨论】:

    • 要禁用 C++ 名称修改,请将它们声明为 extern "C"。谷歌了解确切的语法。
    • 或者在 C 端使用 .def 文件,它会告诉链接器确切地如何命名函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 2016-09-28
    • 2019-08-12
    相关资源
    最近更新 更多