2017-06-25 7 views
0

XcodeでC/C++ダイナミックライブラリを作成しようとしています。.dylibライブラリパッケージ(またはそれを呼び出すもの)と[DLLImport]にコンパイルします。 NETコア。XcodeでC/C++ライブラリを作成し、C#.NETCoreでインポートします

理由:中国の企業がデバイスを開発し、ソフトウェアにデバイスを統合するために、Borland C++でデモライブラリを作成して統合をテストしました。

Xcodeで書かれたC++ライブラリを.NET CoreまたはXamarinを使用してアプリケーションにインポートすることが可能かどうかを知りたいと思います。

今私はC/C++でルーキーです。マイクロソフトが提供するクロスプラットフォームソリューションの新機能です。しかし、this github questionDLLImportによれば、Macで動作するはずです。今私はどのように不思議に思っています。

ただ、いくつかの異なる方法を試し

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; 
} 

:C++ライブラリを書くために私の最善の努力でそう

、そこに... これはにコンパイルされますこれを実行するとき

[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上で、私は 'OpenImageFile' という名前のエントリポイントを見つけることができませんSystem.EntryPointNotFoundException

を得る:私は.NETのコアコンソールアプリケーションにすることをインポート10

DLL 'libtestmachw.dylib'にあります。

私はちょうど私が彼らの私は自分のコードが.dylibにコンパイルを取得するために中国の会社に指示することができます上から、.NETCoreアプリケーション内の関数をインポートできるかどうかテストしたいです。誰が私を助けたり、私を正しい方向に向けることができますか?

このマイクロソフトのページには、私はc/C++側で何か間違っていると思われます。 https://docs.microsoft.com/en-us/dotnet/standard/native-interop

+0

'extern" C "{... your code ...}'ブロックの '.h'ファイルにコードをラップしてみてください。さらに詳しい情報:https://stackoverflow.com/q/8534917/3740093 –

+0

関数に '__declspec(dllexport)'を追加しなければならないかもしれません(上で共有したリンクのように)。 –

+1

@VisualVincent '__declspec(dllexport)'はWindowsのみのもので、他のプラットフォームでは必要ありません。 –

答えて

2

Cの関数のみを呼び出すことはできません。また、これらの関数は標準のC規則を使用してエクスポートする必要があるため、C++ではextern "C"も追加する必要があります。

サンプルでの問題は、TAPIFunc::OpenImageFileがインポートできないC++関数であることです。

たとえば、.cppファイルで定義されているこの関数を使用できます。NETコア:

別のトリック

[DllImport("my.dylib")] 
private static extern int Bridge_OpenFile([MarshalAs(UnmanagedType.LPStr)]string filename); 

を使用して

extern "C" int32_t Bridge_OpenFile(char* filename) { 
    // you can do some C++ calls here 
    return 0; 
} 

:あなたは同じC#のコードを持つことができますので、CoreCLRプロービングの一部として自動的にlib.dylibが追加されますので、DllImportはちょうどtestmachwで使用することができ、実行されるプラットフォームによってはlib{foo}.dyliblib{foo}.so{foo}.dllと一致します。

関連する問題