How to create a DLL that will be used in C#
-
18-04-2021 - |
Pergunta
I have ICOP VDX-6354 board running Win CE. I'm trying to control the buzzer of the board from my C# program. I tried all the playsound etc "coredll.dll" platform invokes. none of them worked so far. So my last chance is to create my own DLL.
unsigned char inp(short addr)
{
unsigned char cValue;
_asm
{
mov dx, addr
in ax, dx
mov cValue, al
}
return cValue;
}
void outp(int addr, unsigned char val)
{
__asm
{
push edx
mov edx, DWORD PTR addr
mov al, BYTE PTR val
out dx, al
pop edx
}
}
bool MyBeep(DWORD dwFreq, DWORD dwDuration)
{
outp(0x43, 0xb6); // Set Buzzer
outp(0x42, (0x1234dc / dwFreq)); // Frequency LSB
outp(0x42, (0x1234dc / dwFreq) >> 8); // Frequency MSB
outp(0x61, inp(0x61) | 0x3); // Start beep
Sleep(dwDuration);
outp(0x61, inp(0x61) & 0xfc); // End beep
return TRUE;
}
The code above is available in the datasheet of the board. I want to compile it as a DLL then invoke it in my C# program like
[DllImport("Buzzer.dll", EntryPoint = "MyBeep")]
public static extern void MyBeep(uint dwFreq, uint dwDuration);
I used a prefix as follows when I compiled:
extern "C" __declspec(dllexport) bool MyBeep(DWORD dwFreq, DWORD dwDuration)
So that hopefully I would be able to control the buzzer. My problem is I couldn't be successful compiling it. I followed the steps here but it didn't help me.
What should I do step by step?
EDIT:
I think I built the DLL. I tried another way to build the DLL found here.
Now, I copied the DLL to my C# startup project's Debug folder(Other DLLs of the project are also in this folder). Then I try to invoke MyBeep function from MyBeep.DLL in my C# project by:
[DllImport("MyBeep.dll", EntryPoint = "MyBeep")]
public static extern bool MyBeep(UInt32 dwFreq, UInt32 dwDuration);
But it gives the following exception.
Can't find PInvoke DLL 'MyBeep.dll'.
Am I missing something? Please check the links given above that I cheated to build the DLL to understand what I did so far. Regards.
Solução
Even though the error message suggests otherwise, you should check the name of the exported function. For Win32 I always use this tool. For a CE dll, maybe DUMPBIN /EXPORTS works.
The functon name is likely to be called __MyBeep
: I believe this prefix is a C convention.
Outras dicas
There's two issues that you've got:
You need to build the dll, not try and debug it. If it's in the same project as your C# project then set the C# project as the startup project (right-click on the project file), if not you'll just have to select Build rather than Start Debugging (if you're using shortcut keys this will probably be Ctrl+Shift+B [if using the C# environment setup] or F7 [if you're using the C++ environment setup]).
You need to have the DLL in the right location. If you want to automate this then just add a post-build step to the C++ project (project properties, build actions if I recall correctly, and post-build) which does something like
copy "$(TargetPath)" "$(SolutionDir)\CsProj\bin\$(ConfigurationName)\*.*"
Some of those macros might be a little off, but you should get the general idea.
EDIT: You also need to make sure that your C++ project is building before your C# project. Right-click on your C# project file, and go to Project Dependencies, then tick the C++ library in the Depends on box. To make sure your post-build step is working try just building the C++ project on its own and checking it copies the DLL to the correct directory in your C# project. It'll flag errors in the output window if it doesn't. If you followed that tutorial to create a DLL you should be ok.