user488792
user488792

Reputation: 2013

BadImageFormatException error when using C++ .dll function for C#?

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

Answers (2)

Sarfaraz Nawaz
Sarfaraz Nawaz

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

Eilistraee
Eilistraee

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

Related Questions