【问题标题】:Create C/C++ library in Xcode and import it in C# .NETCore在 Xcode 中创建 C/C++ 库并将其导入 C# .NET Core
【发布时间】:2017-06-25 10:53:25
【问题描述】:

我正在尝试在 Xcode 中编写一个 C/C++ 动态库,将其编译为 .dylib 库包(或您所称的任何名称)并在 .NET Core 中编译为 [DLLImport]

关于原因的一些背景知识:一家中国公司为我们开发了一种设备,为了将他们的设备集成到我们的软件中,他们用 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

无法在 DLL“libtestmachw.dylib”中找到名为“OpenImageFile”的入口点。

我只是想测试我是否可以在 .NETCore 应用程序中导入函数,从他们那里我可以指示中国公司将他们的代码编译成.dylib。谁能帮助我或为我指明正确的方向?

这个微软页面显示它是可能的,所以我猜我在 c/c++ 方面做错了什么? https://docs.microsoft.com/en-us/dotnet/standard/native-interop

【问题讨论】:

  • 尝试将.h文件中的代码封装在extern "C" { ...your code... }块中。更多信息:stackoverflow.com/q/8534917/3740093
  • 您可能还需要将__declspec(dllexport) 添加到函数中(如我在上面分享的链接中所见)。
  • @VisualVincent __declspec(dllexport) 仅适用于 Windows,在其他平台上不需要。
  • @MartinUllrich:不知道,谢谢!

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


【解决方案1】:

您不能调用 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 取决于运行的平台。

【讨论】:

    猜你喜欢
    • 2013-12-11
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多