我正在尝试在 Xcode 中编写一个 C/C++ 动态库,将其编译为 .dylib
库包(或任何你所说的名称)和 [DLLImport]
它位于 .NET Core 中。
关于原因的背景知识:一家中国公司为我们开发了一款设备,为了将他们的设备集成到我们的软件中,他们用 Borland C++ 编写了一个演示库来测试集成,结果成功了。
现在我想知道我们是否可以使用 .NET Core 或 Xamarin 将用 Xcode 编写的 C++ 库导入到我们的应用程序中。
现在我是一个C/C++菜鸟,对微软提供的跨平台解决方案也有点陌生。但根据this github question DLLImport
应该可以在 Mac 上运行。现在我想知道如何。
所以,我尽最大努力编写一个 C++ 库:
ApiFunc.h
#ifndef ApiFuncH
#define ApiFuncH
double mean(double x, double y);
typedef void (*SignalHandler)(int signum);
typedef int (*OPEN_IMAGE_FILE)(char*);
extern OPEN_IMAGE_FILE open(char *FileName);
extern SignalHandler signal(int signum, SignalHandler handler);
class TAPIFunc
{
public:
int OpenImageFile(char *FileName);
};
#endif
ApiFunc.cpp
#pragma hdrstop
#include "ApiFunc.h"
double mean(double x, double y){
return x * y;
}
int TAPIFunc::OpenImageFile(char *FileName)
{
return 5;
}
只是尝试一些不同的方法...
所以这会编译为 libtestmachw.dylib
我将其导入到我的 .NET Core 控制台应用程序中:
[DllImport("libtestmachw.dylib", EntryPoint = "mean")]
private static extern double mean(double x, double y);
[DllImport("libtestmachw.dylib")]
private static extern int OPEN_IMAGE_FILE(string fileName);
[DllImport("libtestmachw.dylib")]
private static extern int OpenImageFile(string fileName);
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Console.WriteLine("Let's try to communicate with a Mac dylib library");
Console.WriteLine("We are now going to invole function 'mean' of libtestmacw.dylib");
try
{
double result = mean(2, 4);
Console.WriteLine("yes, we made it! Result:" + result);
}
catch (Exception e)
{
Console.WriteLine("Opes that didn't work!");
Console.WriteLine(e);
}
Console.WriteLine("We are now going to invole function 'OPEN_IMAGE_FILE' of libtestmacw.dylib");
try
{
int result = OPEN_IMAGE_FILE("SomeFile.png");
Console.WriteLine("yes, we made it! Result:" + result);
}
catch (Exception e)
{
Console.WriteLine("Opes that didn't work!");
Console.WriteLine(e);
}
Console.WriteLine("We are now going to invole function 'OpenImageFile' of libtestmacw.dylib");
try
{
int result = OpenImageFile("SomeFile.png");
Console.WriteLine("yes, we made it! Result:" + result);
}
catch (Exception e)
{
Console.WriteLine("Opes that didn't work!");
Console.WriteLine(e);
}
Console.ReadLine();
}
在 Mac 上运行此程序时,我收到 System.EntryPointNotFoundException
Unable to find an entry point named 'OpenImageFile' in DLL 'libtestmachw.dylib'.
我只是想测试我是否可以在.NETCore应用程序中导入函数,从此我可以指示中国公司将他们的代码编译成.dylib
。谁可以帮助我或为我指明正确的方向?
这个 Microsoft 页面显示这是可能的,所以我猜我在 c/c++ 方面做错了什么? https://learn.microsoft.com/en-us/dotnet/standard/native-interop
最佳答案
您不能调用 C++ 函数,只能调用 C 函数。此外,这些函数需要使用标准 C 约定导出,因此在 C++ 中您可能还需要添加 extern "C"
。
您的示例中的问题是 TAPIFunc::OpenImageFile
是无法导入的 C++ 函数。
例如,在 .cpp
文件中定义的函数可以在 .NET Core 中使用:
extern "C" int32_t Bridge_OpenFile(char* filename) {
// you can do some C++ calls here
return 0;
}
使用
[DllImport("my.dylib")]
private static extern int Bridge_OpenFile([MarshalAs(UnmanagedType.LPStr)]string filename);
另一个技巧:DllImport
可以仅与 testmachw
一起使用,因为 CoreCLR 会自动添加 lib
和 .dylib
作为探测的一部分,因此您可以拥有相同的 C# 代码,并且它将匹配 lib{foo}.dylib
、lib{foo}.so
和 {foo }.dll
取决于运行的平台。
关于c# - 在 Xcode 中创建 C/C++ 库并将其导入到 C# .NET Core 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44745613/