如何创建一个可以在C#中使用的DLL

9

我有一个运行Win CE的ICOP VDX-6354板,我试图从我的C#程序控制板上的蜂鸣器。我尝试了所有的playsound等"coredll.dll"平台调用,但到目前为止都没有成功。所以我最后的机会是创建自己的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;
}

上面的代码可以在板子的数据手册中找到。我想将其编译为DLL,然后在我的C#程序中调用它,如下所示:

[DllImport("Buzzer.dll", EntryPoint = "MyBeep")]
public static extern void MyBeep(uint dwFreq, uint dwDuration);

我在编译时使用了以下前缀:

extern "C" __declspec(dllexport) bool MyBeep(DWORD dwFreq, DWORD dwDuration)

希望我能控制蜂鸣器。我的问题是编译时无法成功。我按照这里的步骤进行了操作,但没有帮助我。

我应该怎么做呢?

编辑:

我想我已经构建了DLL。我尝试了另一种构建DLL的方法,在这里找到

现在,我将DLL复制到我的C#启动项目的Debug文件夹中(项目的其他DLL也在此文件夹中)。然后,我尝试通过以下方式从MyBeep.DLL在我的C#项目中调用MyBeep函数:

[DllImport("MyBeep.dll", EntryPoint = "MyBeep")]
public static extern bool MyBeep(UInt32 dwFreq, UInt32 dwDuration);

但是它会出现以下异常。

找不到PInvoke DLL 'MyBeep.dll'。

我是否遗漏了什么?请查看上面提供的链接以了解我迄今为止所做的事情。 谢谢。


1
什么失败了?有错误信息吗?你是如何构建的?简而言之,请提供更多细节。 - David Heffernan
它只是无法成功编译。正如我在问题中所述,我逐步按照一个“如何”教程进行操作。当我尝试编译时,它要求“调试会话的可执行文件”。而且在 Dropbox 上唯一可用的可执行文件是 RegSvr32。当我选择 RegSvr32 并继续时,它会在单独的警告屏幕上显示使用方式:regsrv32 [/u][/s][/n][/i]等,并且编译器不会给出任何错误。 - Oğuz Sezer
1
你无法启动一个 DLL 进行调试(没有可托管它的 exe)。请不要按“播放”(例如,调试)按钮,而是找到“编译但不调试”命令。 - Sam Axe
@OğuzSezer - 如果你需要帮助,请发布编译器提供的错误信息。一个很好的开始是停止尝试调试不是应用程序的东西。我们需要更多的信息...就目前而言...这个问题无法得到答案。 - Security Hound
@Oğuz Sezer - 如果你的应用程序找不到dll文件,那么它就不在正确的位置。你把它放在哪里了?为什么要尝试注册它,你不需要这样做,因为这不是一个COM库。 - Security Hound
显示剩余6条评论
2个回答

1

你有两个问题:

  1. 你需要构建dll,而不是尝试调试它。如果它与你的C#项目在同一个项目中,则将C#项目设置为启动项目(右键单击项目文件),否则你只需选择“生成”而不是“开始调试”(如果你使用快捷键,则可能是Ctrl+Shift+B [如果使用C#环境设置]或F7 [如果使用C++环境设置])。

  2. 你需要将DLL放在正确的位置。如果你想自动化这个过程,只需向C++项目添加一个后期构建步骤(项目属性,构建操作,如果我没记错的话,是后期构建),其中执行类似于 copy "$(TargetPath)" "$(SolutionDir)\CsProj\bin\$(ConfigurationName)\*.*" 的操作。

其中一些宏可能有点偏差,但你应该能够理解大致意思。

编辑:您还需要确保在C#项目之前构建C++项目。右键单击C#项目文件,转到项目依赖项,然后在“依赖于”框中选中C++库。为了确保您的后期构建步骤正常工作,请尝试仅构建C++项目并检查它是否将DLL复制到C#项目中的正确目录。如果没有,则会在输出窗口中标记错误。如果您按照该教程创建DLL,则应该没问题。


0

尽管错误信息表明了另外一种情况,但你应该检查导出函数的名称。对于Win32,我总是使用this tool。对于CE dll,也许DUMPBIN /EXPORTS可以起作用。

函数名很可能被称为__MyBeep:我相信这个前缀是C语言的惯例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接