如何在 Xamarin 中使用 DLLIMPORT?

Posted

技术标签:

【中文标题】如何在 Xamarin 中使用 DLLIMPORT?【英文标题】:How to use DLLIMPORT in Xamarin? 【发布时间】:2019-11-26 16:43:42 【问题描述】:

我在 Xamarin 中有一个用于 mac 的控制台项目,并且想使用来自外部库的 c++ 函数。但不幸的是,当我尝试像这样使用 DLLIMPORT (c#) 时:

[DllImport('path to the library')]
static extern double sum(double x, double y);

public static void Main(string[] args)

   Console.WriteLine(sum(2,2));

我得到 System.DLLNotFoundException。但是它适用于系统库:

[DllImport("/usr/lib/libSystem.dylib")]
static extern IntPtr dlopen(string path, int mode);

这是我所有的代码

1) main.cpp(来自 lib.dylib 库):

extern "C" double sum(double x, double y) 
   return x + y;

2) Program.cs(来自 Xamarin C# 项目):

using System;
using System.Runtime.InteropServices;

namespace Project 
   class MainClass 
      [DLLImport("/full/path/to/lib.dylib")]
      static extern double sum(double x, double y);

      public static void Main(string[] args) 
         Console.WriteLine(sum(2,2));
         Console.ReadKey();
      
   

我使用 XCode 创建库 (.dylib),但不确定我是否做对了所有事情。

【问题讨论】:

docs.microsoft.com/en-us/xamarin/ios/platform/… 【参考方案1】:

我想我明白出了什么问题。 我在 c# 中引用库的方式是可以的。问题是我错误地构建了库。让我解释一下。

要创建库,我使用 Mac OS 的 XCode 库项目(框架:无(普通 C/C++ 库)):

press here to view image

这意味着我在“构建设置”选项卡中的“架构”面板默认如下所示:

press here to view image

注意突出显示的属性。它们很重要。 因此,如果我保持原样并按 cmd+B(构建),我将获得一个库(.dylib 文件)。但是如果我去终端并用 lipo 检查这个库,我会得到:

lipo -info path/to/the/library.dylib
Non-fat file: path/to/the/library.dylib is architecture: x86_64

但如果我对 /usr/lib/libSystem.B.dylib 库(或任何其他系统 .dylib 库)执行相同操作,则输出会有所不同:

lipo -info /usr/lib/libSystem.B.dylib
Architectures in the fat file: /usr/lib/libSystem.B.dylib are: x86_64 i386 

当我检查我自己的库时,很容易猜到我想看到同样的结果。要修复它,请返回“架构”面板并执行以下操作:

1) 检查您的“有效架构”属性。它的值必须是“i386 x86_64”(不带引号)。

2) 对于“仅构建活动架构”属性选择“否”。现在,您的“架构”面板必须如下所示:

press here to view image

3) 按下“架构”属性。选择“其他...”作为值并在打开的窗口类型中:

$ARCHS_STANDARD
x86_64
i386

press here to view image

因此,您的“架构”面板必须如下所示:

press here to view image

就是这样!现在你可以建立你的图书馆了!如果你现在用 lipo 检查它,你会得到:

lipo -info /path/to/your/library.dylib
Architectures in the fat file: /path/to/your/library.dylib are: x86_64 i386

我不确定有什么区别,但奇怪的是它解决了问题。现在我可以从 c# 调用我的 c++ 函数了。

有人知道会发生什么吗?

【讨论】:

【参考方案2】:

使用 DLL 依赖项中的方法的最佳方式是将其添加到项目的依赖项中。为此,请执行以下操作:

    右键单击要添加依赖的命名空间,然后转到添加->“引用...”; 参考管理器将打开。点击“浏览...”并找到您的 DLL 文件。 单击“确定”,您的 DLL 将作为依赖项添加到您的项目中。

要在 C# 文件中使用其方法,请在文件顶部使用“使用”语法,例如:using Xamarin.Forms.GoogleMaps.Clustering;。之后,在 DLL 中编译的代码将可供您在文件中使用。

【讨论】:

感谢您的回答 Mateus!不幸的是,这不起作用,因为 Xamarin 不允许像这样选择我的“.dylib”库。也许有不同的方法? .dylib 代表“动态库”,与 Windows .dll 的概念相同。这个文件是你生成的吗?如果是这样,您可能可以将其重新编译为 .dll,以便将其导入 Visual Studio。 我刚看到你说你是用 XCode 编译的。如果您选择走这条路,您将需要将您的程序从 Mac 格式交叉编译为 Windows 格式。这是可能的,但应该有一个更简单的选择。我的猜测是,如果您在 Mac 上运行 Visual Studio,它只会接受“.dylib”文件,因为它在 Windows 上接受“.dll”。

以上是关于如何在 Xamarin 中使用 DLLIMPORT?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中使用 [DllImport("")]?

Xamarin效果第十二篇之控制祖传PLC

在 Visual C++ 中使用 dllimport

Xamarin Mac,将 CGImage 转换为 .NET System.Drawing.Image

dllimport如何在非托管dll中获取哪个应用程序调用了函数

如何在 C# 中将 Byte* 从 C++ 转换为 Byte[]