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

时间:2018-07-16 16:21:47

标签: c# c++ c cygwin dllimport

我尝试用为Linux编写的C / C ++程序制作DLL。我在Cygwin Shell中运行它,并为DLL制作了接口。我还使用了this来调用该函数,但是现在DLL想要在c文件中分配内存时挂起。

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

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

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

test.h

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

test.c

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

我在Cygwin外壳中这样编译它

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 ();
}

1 个答案:

答案 0 :(得分:1)

尝试将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[](但不是一个ref [] )...可能是:

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