我尝试用为 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# 中以多种方式进行翻译。
每个带有 *
的参数都可以是 ref
、out
或 []
(但 < 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/