简体   繁体   中英

Unmanaged DLL to Managed C# win32 application. Entry with Class

My problem is trying to access a defined dll function inside a class called function.

namespace MathLibrary
{
extern "C" 
{
    __declspec(dllexport) double Functions::Add(double a, double b)
    {
        return a + b;
    }

    __declspec(dllexport) double Functions::Multiply(double a, double b)
    {
        return a * b;
    }

    __declspec(dllexport) double Functions::AddMultiply(double a, double b)
    {
        return a + (a * b);
    }
}

}

This is what I have From C++ and created MathLibrary.dll Now I would like to use it in C# so I tried PInvoke method. I am not sure what procedure is this called, please inform me I am wrong.

class Program
{
    [DllImport("MathLibrary.dll", CallingConvention =        CallingConvention.Cdecl)]
    public static extern double Add(double a, double b);

    static void Main(string[] args)
    {
        double myNumber = Add(10, 5); <- this is the Line. I suspect that it is because the Add is inside a class name Functions that I why I can't Access it and having error that there is no Entry point for the method Add.

        Console.WriteLine(myNumber);
    }
}

The MathLibrary.h looks like this and I don't even know if it is still necessary to add __declspec(dllexport) on the MathLibrary.cpp, example above. Since I already have #ifdef for the dllexport in here.

#pragma once

#ifdef MATHLIBRARY_EXPORTS  
#define MATHLIBRARY_API __declspec(dllexport)   
#else  
#define MATHLIBRARY_API __declspec(dllimport)   
#endif  

namespace MathLibrary
{
// This class is exported from the MathLibrary.dll  
class Functions
{
public:
    // Returns a + b  
    static MATHLIBRARY_API double Add(double a, double b);

    // Returns a * b  
    static MATHLIBRARY_API double Multiply(double a, double b);

    // Returns a + (a * b)  
    static MATHLIBRARY_API double AddMultiply(double a, double b);
};
}

So going back to the Question. I suspect that I have to Define the DLL function from the PInvoke or DLLImport that the Method is inside the Function CLass, which I am not aware how to do.

Error is. Cannot find Entry Point Add .

You are pretty close to making it work, and your suspicion is correct. In order for your .NET code to PInvoke into a DLL, it needs to find the expected C-style function symbol in your DLL. Since your DLL is being built with C++ code (regardless of the extern "C" you have), the function name is being mangled and so .NET cannot find what it is expecting.

Solution

To fix this, your function declarations need to be pure C (and do keep the extern "C" around those declarations). This means no namespaces, no classes, no references, etc. However, the function implementation code can be C++ if you want. You just need .NET and your DLL to agree on the declarations (interfaces).

Suggestion

If for some reason you need to keep all that C++ code the way it is (because other code is using it), then just create a new thin C layer on top of it which will be your DLL public interface used by .NET.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM