我尝试用为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 ();
}
答案 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#中以多种方式转换。
每个带有*
的参数可以是ref
,out
或[]
(但不是一个ref []
)...可能是:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int scanJPGfromBUF(ref det_t dets, byte[] bytes1, byte[] chars1);