c# - 在 Xcode 中创建 C/C++ 库并将其导入到 C# .NET Core 中

标签 c# c++ objective-c xcode .net-core

我正在尝试在 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}.dyliblib{foo}.so{foo }.dll 取决于运行的平台。

关于c# - 在 Xcode 中创建 C/C++ 库并将其导入到 C# .NET Core 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44745613/

相关文章:

c++ - 需要帮助来理解 C++ 语法

c++ - 如何存储 VARIANT

iphone - 了解 Objective-C 中的协议(protocol)继承

c# - 为什么我收藏的字符串会截断单词?

c# - 构建是否可以在一个平台上成功而在另一个平台上失败?

c++ - 是否可以使用 DirectX 3D 11 绘制由三角形组成的圆?

objective-c - 为什么 ARC 禁止调用未声明的方法?

objective-c - 带有核心数据,协议(protocol)和读写属性与只读属性声明的怪癖

c# - 为现有 gRPC 服务器生成客户端

c# - .net 4.0 中引用类型的 volatile