Reputation: 2013
I am having trouble with using P/Invoke for C#. Here is the function (written in C++) that I am trying to call from the .dll:
string
BeatTracker::getName() const
{
return "Tempo and Beat Tracker";
}
And here is my code for trying to call this function:
[DllImport("qm-vamp-plugins.dll",EntryPoint="BeatTracker")]
public static extern string getName();
public QMTempo()
{
Console.WriteLine(getName());
}
What seems to be wrong? I am getting a BadImageFormatException. And how can I know what is wrong in future references aside from the vague names the IDE is giving me? I am using Visual Studio 2008 by the way.
Also I am using (but not sure if right) EntryPoint, to let it know that I am using the getName function from the BeatTracker class (because there are also getName functions for other classes, which are included in the single .dll file)
Thanks!
Upvotes: 1
Views: 6702
Reputation: 361782
[DllImport("qm-vamp-plugins.dll",EntryPoint="BeatTracker")]
The EntryPoint
should be getName()
, not BeatTracker
which is a class!
But even then you cannot call that, because getName()
is member function which cannot be callled without instance.
So I would suggest that define free functions in the DLL, and export them. You can use class internally, in the DLL. You can work with handle of classes.
Example,
DLL code:
typedef BeatTracker* PBeatTracker;
typedef PBeatTracker HBeatTracker;
//exported functions
HBeatTracker CreateBeatTracker()
{
return new BeatTracker();
}
void DeleteBeatTracker(HBeatTracker handle)
{
delete handle;
}
string getName(HBeatTracker handle)
{
return handle->getName();
}
C# Code:
[DllImport("qm-vamp-plugins.dll",EntryPoint="CreateBeatTracker")]
public static extern IntPtr CreateBeatTracker();
[DllImport("qm-vamp-plugins.dll",EntryPoint="DeleteBeatTracker")]
public static extern void DeleteBeatTracker(IntPtr);
[DllImport("qm-vamp-plugins.dll",EntryPoint="getName")]
public static extern string getName(IntPtr);
public QMTempo()
{
IntPtr handle = CreateBeatTracker();
Console.WriteLine(getName(handle));
DeleteBeatTracker(handle);
}
Upvotes: 3
Reputation: 8290
This exception can be caused by a mismath between the .NET runtime proc architecture used and the imported dll one.
More precisely:
Do you use a 64bit Windows? The runtime will, by default, run in 64bit. If your C++ library was compiled targeting 32bit, you will get a BadFormatException upon library loading. The Same goes if your .NET app is running 32bit and your C++ library was compiled targeting x64.
If you can recompile the library, do it. Otherwise you can force the .NET runtime to use a specified architecture at compilation, but it will prevent it from running on the other architecture. It's your choice ;) When coding against .NET or java, we tend to forget what really happen under the hood.
Upvotes: 8