Я пытаюсь написать динамическую библиотеку C / C ++ в Xcode, скомпилировать ее в .dylib
пакет библиотеки (или как вы это называете) и [DLLImport]
это в .NET Core.
Немного предыстории о том, почему: китайская компания разрабатывает для нас устройство, для интеграции своего устройства в наше программное обеспечение они написали демонстрационную библиотеку на Borland C ++ для проверки интеграции, и это сработало.
Теперь я хочу знать, возможно ли нам импортировать библиотеку C ++, написанную на Xcode, в наше приложение, используя .NET Core или Xamarin.
Сейчас я новичок в C / C ++ и немного новичок в кроссплатформенных решениях, предоставляемых Microsoft. Но согласно этот вопрос GitHub 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
Невозможно найти точку входа с именем «OpenImageFile» в DLL «libtestmachw.dylib».
Я просто хочу проверить, могу ли я импортировать функции внутри приложения .NETCore, с этого момента я могу дать указание китайской компании собрать их код в .dylib
, Кто может помочь мне или указать мне правильное направление?
На этой странице Microsoft показано, что это возможно, поэтому я полагаю, что я делаю что-то не так на стороне c / c ++? https://docs.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
в зависимости от платформы запустить.
Других решений пока нет …