c# - 在 C# 中调用 Cygwin GCC DLL 在 malloc 上挂起

标签 c# c++ c cygwin dllimport

我尝试用为 Linux 编写的 C/C++ 程序创建一个 DLL。我让它在 Cygwin shell 中运行,并为 DLL 创建了一个接口(interface)。我也用过 this调用该函数,但现在当 DLL 想要在 c 文件中分配内存时挂起。

我将问题分解为这个简单的程序: malloctest.cpp 像这样锁

#include <stdlib.h>
#include "test.h"
extern "C" __declspec(dllexport) int malloctest();

int malloctest(){
    int check = test();
    return check;
}

测试.h

#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
int test();
#ifdef __cplusplus
}
#endif

测试.c

#include "test.h"
int test(){
    int * array = malloc(42 * sizeof(int));
    free(array);
    return 42;
}

我在Cygwin shell中是这样编译的

gcc -c malloctest.cpp test.c
gcc -shared -o malloctest.dll malloctest.o test.o

我在 C# 中这样调用它:

class Program
{

    [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
    static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

    [DllImport("kernel32", SetLastError = true)]
    static extern IntPtr LoadLibrary(string lpFileName);


    public delegate int test();
    static void Main(string[] args)
    {
        IntPtr pcygwin = LoadLibrary("cygwin1.dll");
        IntPtr pcyginit = GetProcAddress(pcygwin, "cygwin_dll_init");
        Action init = (Action)Marshal.GetDelegateForFunctionPointer(pcyginit, typeof(Action));
        init();

        IntPtr libptr = LoadLibrary("malloctest.dll");
        IntPtr funcptr = GetProcAddress(libptr, "malloctest");
        test malloctest = (test)Marshal.GetDelegateForFunctionPointer(funcptr, typeof(test));
        int check = malloctest(); //hold
        Console.WriteLine(check);
    }
}

现在它只是挂起而没有错误。 如果我在 malloctest.cpp 中使用 malloc,它会起作用,但只要我调用使用 malloc 的 C 文件,dll 就会挂起。

编辑: 这是我真正的界面.h

extern "C" {
  typedef struct det det_t;
  struct det{
     int id;
     int hamming;
     float goodness;
     float decision_margin;
     double c[2];
     double lu[2];
     double ld[2];
     double ru[2];
     double rd[2];
 };
  __declspec(dllexport) int scanJPGfromBUF(det_t * dets, uint8_t *, char *);
  __declspec(dllexport) int test ();
}

最佳答案

尝试将 delegate 更改为:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int test();

.NET 的默认值应该是 Stdcall,但 C 中的默认值是 Cdecl

我会将 C 结构翻译成:

struct det
{
    int id;
    int hamming;
    float goodness;
    float decision_margin;
    double c1;
    double c2;
    double lu1;
    double lu2;
    double ld1;
    double ld2;
    double ru1;
    double ru2;
    double rd1;
    double rd2;
}

所以我会删除所有数组并将它们转换为多个元素。 C 方法的签名可以在 C# 中以多种方式进行翻译。

每个带有 * 的参数都可以是 refout[](但 < strong>不是 ref [])... 所以它可能是:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int scanJPGfromBUF(ref det_t dets, byte[] bytes1, byte[] chars1);

关于c# - 在 C# 中调用 Cygwin GCC DLL 在 malloc 上挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51366230/

相关文章:

c# - 从 .NET 将类型序列化为 XML

python - 通过引用传递的 SWIG Python 固定大小数组

c - 如何在 .NET 应用程序中执行 C 代码?

c - 如何打印在 C 函数 main 中初始化的二维数组?

c# - .Net Core/控制台应用程序/配置/XML

c# - 强大的随机数生成

c# - 在 IronPython 中导入数学失败

c++ - 如何在 QListWidget 下添加这样的组按钮?

c++ - 如何创建具有运行时间限制的数据结构

c++ - C 预处理文件中这些不熟悉的行是什么?