Reputation: 10321
I am trying to write an C/C++ dynamic library in Xcode, compile it to an .dylib
library package (or whatever you call that) and [DLLImport]
it in .NET Core.
Little background on why: A Chinese company develops a device for us, for integrating their device in our software they wrote a demo library in Borland C++ to test the integration and that worked out.
Now I want to know if it is possible for us to import an C++ library, written in Xcode, into our application as well, using .NET Core or Xamarin.
Now I am a rooky at C/C++ and I am a bit new to the cross platform solutions provided by Microsoft. But according to this github question DLLImport
should work on Mac. Now I am wondering how.
So, in my best effort to write a C++ library:
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;
}
Just trying some different methods out there...
So this compiles to a libtestmachw.dylib
I import that into my .NET Core console application:
[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();
}
When running this, on Mac, I get an System.EntryPointNotFoundException
Unable to find an entry point named 'OpenImageFile' in DLL 'libtestmachw.dylib'.
I just want to test if I can import functions inside a .NETCore application, from their on I can instruct the Chinese company to get their code compiled into a .dylib
. Who can help me out or point me into the right direction?
This Microsoft page shows it is possible, so I am guess I am doing something wrong at the c/c++ side? https://learn.microsoft.com/en-us/dotnet/standard/native-interop
Upvotes: 2
Views: 1932
Reputation: 100751
You cannot call C++ functions, only C functions. Also, these functions need to be exported using standard C conventions, so in C++ you might need to add an extern "C"
as well.
The problem in your sample is that TAPIFunc::OpenImageFile
is a C++ function that cannot be imported.
For example, this function defined in a .cpp
file can be used in .NET Core:
extern "C" int32_t Bridge_OpenFile(char* filename) {
// you can do some C++ calls here
return 0;
}
using
[DllImport("my.dylib")]
private static extern int Bridge_OpenFile([MarshalAs(UnmanagedType.LPStr)]string filename);
Another trick: DllImport
can be used with just testmachw
since CoreCLR will add lib
and .dylib
automatically as part of the probing so you can have the same C# code and it will match lib{foo}.dylib
, lib{foo}.so
and {foo}.dll
depending on the platform run on.
Upvotes: 4