Click here to Skip to main content
15,886,860 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Greetings all,

I've recently started with C#. I have a project which requires the use of unmanaged code. I have access to a .lib and H file to an API. I realize that this has been covered previously. eg (How to create a DLL library in C and then use it with C#[^] ) but my header file seems a little different to the one used in that example.

I am trying to turn on a buzzer on a CE device. I would like to create a form using C#. I understand I have to create a wrapper but struggling a little with the concepts. The contents of the header file looks like this:

#ifndef __BUZZERIF_H__
#define __BUZZERIF_H__


#if __cplusplus
extern "C" {
#endif

BOOL BuzzerState(DWORD dwState) ;
DWORD BuzzerRegRead(DWORD RegNum) ;

#if __cplusplus
}
#endif

#endif //__BUZZERIF_H__

-----------------------------------------------------------------------


The following C code turns the buzzer "on"

C#
DWORD dwVal ;
dwVal = 0x0001 ;
if ( !BuzzerState(dwVal) )
{
printf("BuzzerState() FAILED\r\n") ;
}
else
{
printf("Buzzer state set to = %u \r\n", dwVal) ;
}




If anyone could provide me with pointers as to how I can create the wrapper so that i can set/call the function in C# (or even the simplest example code), that would be truly appreciated.
Posted

One way is using C++/CLI and use your unmanaged DLL directly as it is done if C++. Using C++/CLI, create a public wrapper managed ("ref") class. You wrapper project should be mixed-mode (managed+unmanaged). On output, you get a library which can be uses as a normal .NET library. You can reference by any other .NET Assembly.

The second way is using C# only and P/Invoke. Your case is extremely simple; how come it could be a problem? Do this:

C#
//I show only actually needed using clauses:
using dword = System.UInt32;
using DllImportAttribute = System.Runtime.InteropServices.DllImportAttribute;

class MyWrapper {
    const string LibraryName = "MyUnmanaged.DLL";
    
    [DllImport(LibraryName, EntryPoint = "BuzzerState")] 
    internal static extern bool BuzzerState(dword dwState);

    [DllImport(LibraryName, EntryPoint = "BuzzerRegRead")] 
    internal static extern dword BuzzerRegRead(dword RegNum);
}


The named parameter EntryPoint is redundant here, but I recommend to use it because the exported name could be different (name mangling, which is your case is suppressed by "extern C"). It's best to check up what is actually exported using some binary dump tool such as "dumpbin.exe" — use it from Visual Studio Command Prompt.

See:
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.aspx[^],
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.aspx[^],
Name mangling, aka name decoration: http://en.wikipedia.org/wiki/Name_decoration[^].

—SA
 
Share this answer
 
v4
Hi SAKryukov,

thank you for your reply. I will read up on those links.

In your second option, you have mentioned a .DLL, in my case I don't have a DLL. I have a .Lib Can I use the .Lib file in the same way ? Perhaps not.

I found an article that explains how to create the wrapper. http://tom-shelton.net/index.php/2008/12/11/creating-a-managed-wrapper-for-a-lib-file/comment-page-1/#comment-108[^]

But I am stuck on step 6 because it looks different to my header file. My apologies if this is a silly problem, I am still learning all this programming stuff.

Anybody know what I can do in step six for the header file I have listed?


J
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900