5

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".

Community
  • 1
  • 1
Hiep Dang
  • 97
  • 1
  • 9
  • 1
    As the links say, use `DllImport`. **Do not** attempt to add a reference by right-clicking **References** and choosing **Add**. Just use your existing `DllImport` c# code –  May 20 '15 at 04:13
  • @MickyDuncan: Thanks for reply. But C# code I have posted does not meet my requirement. When mymethod call, value of "buf" must change. Follow C# code, I just get an error message that "the value of 'key' is invalid". This happen when the variable of key not enough 8 characters. – Hiep Dang May 20 '15 at 04:34
  • Update your question to reflect these new requirements –  May 20 '15 at 04:44
  • Please put full exception message of the error when running your code. It will help us to distinguish what is exactly your problem. – M.Mahdipour May 20 '15 at 06:33
  • @M.Mahdipour: Without exception error occurs with C# code. With C++ Code, when I call method with key = "123456789", I get buf = "2995796360". If key haven't between 8-13 characters, you must get mesage: "the value of 'key' is invalid". All messages return are defined by others. With C# Code, when I call method with key = "123456789", I get message like key haven't between 8-13 characters. – Hiep Dang May 20 '15 at 07:14

3 Answers3

2

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.

Hiep Dang
  • 97
  • 1
  • 9
xanatos
  • 109,618
  • 12
  • 197
  • 280
  • Thanks for your solutions. I had to follow but still error occurred. – Hiep Dang May 20 '15 at 05:13
  • @HiepDang You have to put the `.dll` in the same folder of the `.exe`, and you have to know if your `.dll` has been compiled at 32 bits or at 64 bits. Then set the C# project to Properties->Build->Platform Target x86 if the dll is 32 bits and x64 if the dll is 64 bits. – xanatos May 20 '15 at 06:09
  • mydll is 32 bits, then I set Platform Target x86 too. I think I must use C++/CLI to solved this bug. Thanks for helping! – Hiep Dang May 20 '15 at 06:49
  • I have solved my problem. I have edited your code to improve answers. Thank you! – Hiep Dang May 20 '15 at 10:42
0

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);
zwcloud
  • 4,546
  • 3
  • 40
  • 69
  • Not like you think. Cpp code snippet you see using in Visual C++, and it can work good. But I want to use mydll.dll in C#, and I don't know how to do? – Hiep Dang May 20 '15 at 06:52
0

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.

Karan Singh
  • 876
  • 1
  • 6
  • 12