Hiep Dang
Hiep Dang

Reputation: 97

How to use C++ dll from C#

I'm trying include c++ library (DLL) in my c# project but every time I do that I get following error message in VS2012

A reference to 'C:\Users\HiepDang\Desktop\mydll.dll' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.

When I'm trying add Com+ Component, I get following error message in window

One or more files do not contain components or type libraries. These files cannot be installed.

Error 80110425 occurred.

An unknown error occured. You should check all documentation for a solution. If no further information is available, please contract technical support

I'm following thread here and here but my problem not solved.

In C++, I can use dll like:

    //Header
    extern "C" __declspec( dllimport ) int mymethod(const char *key, char *data, size_t buflen);
    
    //Code test
    const char* key = "test";

    char* data = new char[1024];
    int buflen = 1024;
    int result = mymethod(key,data, buflen);

In C#, I use dll as:

    //define dll
    [DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern int mymethod([MarshalAs(UnmanagedType.LPTStr)]string key, [MarshalAs(UnmanagedType.LPTStr)]string data, uint buflen);

    //method test
    private static int testdll() 
    {
        string key = "123456789";
        string buf = string.Empty;
        mymethod(key, buf, 1024);
        return 0;
    }

Can you tell me any solutions to solve it.

P.s: My English is not good. I'm sorry if something inconvenient

Edited: I explain the variable in method in dll. "key" as string input has 8-13 characters, mymethod will be encrypted to generate "buf". I need variable of "buf".

Upvotes: 5

Views: 8453

Answers (3)

zwcloud
zwcloud

Reputation: 4889

In your cpp project, change

extern "C" __declspec( dllimport )

to

extern "C" __declspec( dllexport )

And copy the generated cpp dll file "mydll.dll" to the outdir of your C# project.

By the way, you'd better use byte[] instead of char* for the second argument data if it is not a string but raw binary data.

[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int mymethod([MarshalAs(UnmanagedType.LPTStr)]string key, byte[] data, uint buflen);

byte array is automatically marshalled.

Reference on MSDN

Use it like below.

var key = "A key";
var data = new byte[10];
//fill data
mymethod(key, data, (uint)data.Length);

Upvotes: 0

xanatos
xanatos

Reputation: 111810

In C# you have to use StringBuilder()

//define dll
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int mymethod(string key, StringBuilder data, IntPtr buflen);

//method test
private static int testdll() 
{
    string key = "123456789";
    StringBuilder buf = new StringBuilder(1024);
    mymethod(key, buf, (IntPtr)buf.Capacity);
    string buf2 = buf.ToString()
    return 0;
}

Note that size_t is IntPtr in size, because it is 4 bytes on x86 and 8 bytes on x64.

Upvotes: 2

Karan Singh
Karan Singh

Reputation: 906

Also because my DLL is unmanaged (meaning it is an Unmanaged language like C or C++) then according to the specs of DllImport, "Indicates that the attributed method is exposed by a unmanaged DLL as a static entry point". Why can I not use this "DllImport"? If its a c++ com object if you register it with regsvr32 you can add a reference to the dll in visual studio com references tab and usually visual studio creates an dll (I think its called a runtime callable wrapper) which you can see is created with the nameoflibrary.interop.dll. So MyExecRefsDll.dll if were a com object would become MyExexRefs.Interop.dll. But when you add the reference visual studio usually does this for you automatically in managed code. If you create a c++ dll as a com object by using atl template in c++ it is easier to access from dotnet (Iam referencing unmanaged c++ code from a dll which references another dll file (No code copied from the second dll I just reference the tlb, lib, the dll file, and visual studio does everything else.

Upvotes: 0

Related Questions