4

I have a .dll built in C++/CLI and .NET. Therefore, it is targeted to .NET applications. The API is a set of wrappers that uses managed types so it is NET native. I have imported the .dll and added a function like:

[DllImport(@"maplib.dll")]
public static extern bool initialize(string a);

When I call this function in my C# code, it works fine, but if I want to add another function, like..

[DllImport(@"maplib.dll")]
public static extern bool initialize(string a);
public static extern bool runfile(string a, string b);

I get this error when I run my program. It is related to the second function:

"Could not load type 'myapp.main' from assembly 'myapp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because the method 'runfile' has no implementation (no RVA)."

Why does this error occur and how can I fix it?

dnclem
  • 2,818
  • 15
  • 46
  • 64

2 Answers2

17

You must add the DllImport attribute twice if you want two functions:

[DllImport(@"maplib.dll")]
public static extern bool initialize(string a);
[DllImport(@"maplib.dll")]
public static extern bool runfile(string a, string b);

But if your dll is .NET then why not just add a regular reference to it and use it like you would use C# code?

Scott
  • 999
  • 7
  • 13
  • I can add a reference to it, but it doesn't show up when I try to write the using directive, if that made sense. – dnclem Nov 20 '11 at 08:32
  • This is because you have exported the functions as native c++. Try putting them as static in a managed class instead. – Krumelur Nov 20 '11 at 08:39
  • Also make the ref class public and put it in a namespace. – Simon Nov 20 '11 at 08:52
  • @Krumelur what do you mean? I am a bit confused because I am very new to this sort of stuff and the .dll itself wasn't made by me. – dnclem Nov 20 '11 at 09:37
  • @Simon What ref class are you referring to? – dnclem Nov 20 '11 at 09:37
  • The C++/CLI classes in your library. If your library have a C interface and use P/Invoke it is non-sense to use C++/CLI. – Simon Nov 21 '11 at 08:25
2

As I understand it, you have created a library of managed class(es) implemented in C++. You want to use this class library (assembly) in other managed code (written in C#, VB.NET, etc.). Currently, you have exported some methods (your API) as native C++ calls:

public bool initialize(string a) {
    // ...
}

public bool runfile(string a, string b) {
    // ...
}

This is useful if you want to be able to call your library from native C++ code, but if you want to use only managed code to call your library, I suggest that you create your API as managed code:

public ref class MyLibraryFunctions {
    public:
        static bool initialize(string a);
        static bool runfile(string a, string b);
};

This way, you do not need DllImport in your C# code. You can just do:

using Something.MyLibrary;
....
    public void doSomethingThatNeedsMyLibrary() {
       MyLibraryFunctions.initialize(someString);
    }

I hope I understood your question correctly.

Krumelur
  • 31,081
  • 7
  • 77
  • 119