在C#程序中使用C编写的多个DLL

时间:2015-02-12 11:05:14

标签: c# c visual-studio dll

我有一个用C#编写的程序。我想在这个程序中使用C语言编写的DLL。

public class Test
{
    [DllImport(@"C:/.../surcouche2.dll")]
    public static extern int refreshEntities();
}

我将该函数称为:

Test.refreshEntities();

我正在使用Visual Studio。为了创建DLL surcouche2.dll,我创建了一个新的Visual C ++应用程序控制台,然后我选择了DLL并将选项保留为默认值。然后,我告诉VS使用C编译。

功能是:

__declspec(dllexport) int refreshEntities() {
    int ret = 0;
    LibData *n;

    n = newLibData(LIB_MODULES_MODULE_ENTITES, LIB_MODULES_ACTION_SELECT,
            "http://10.0.2.2:4242/WebService1.asmx");
    if (n)
    {
        ret = n->refreshDb(n);
        n->destroy(n);
    }
    return (ret);
}

调用的函数位于另一个DLL(引用)中。但是我得到了这个错误:

system.DllNotFoundException: Impossible de charger la DLL 'C:/.../surcouche2.dll': Le module spécifié est introuvable. (Exception de HRESULT : 0x8007007E)
   à app.Lol.refreshEntities()
   à app.MainWindow..ctor() dans c:\...\MainWindow.xaml.cs:ligne 30

但是,如果我像这样更改函数refreshEntities,那么它可以正常工作:

__declspec(dllexport) int refreshEntities() {
    return (42);
}

第二个DLL使用另一个DLL(都在C中)。我用选项&#34创建了它们;创建一个空项目"所以我没有stdafx.h,...文件。我想这不是问题,因为我可以在第二个DLL中使用第三个DLL中的函数。

2 个答案:

答案 0 :(得分:1)

如果无法解析加载的dll的依赖关系,则会发生此错误。 首先,我建议您将两个本机程序集放在bin文件夹中并更改引用
[DllImport(@"C:/.../surcouche2.dll")][DllImport("surcouche2.dll")]

通常,调试依赖性问题{} {}和Dependency Walker等工具非常有用。首先有助于理解依赖关系是什么,其次是检查你的应用程序是否试图找到它们。

配置Process Monitor以仅显示流程活动,并使用您的应用程序名称应用流程名称过滤器,如下图所示,您将获得您的应用尝试访问的所有文件。它将有助于找到丢失的dll。 Process Monitor filtering

答案 1 :(得分:1)

[DllImport(@"C:/.../surcouche2.dll")]

这是坏主意,您正在预览用户计算机上出现的问题。硬编码DLL的路径就像这样有助于pinvoke编组程序在磁盘上找到DLL文件。但它绝对没有帮助操作系统找到surchouce2.dll需要的DLL。就像包含newLibData()函数的那个​​。

错误消息经常被错误解释。它说它不能加载" surcouche2.dll。这是准确的,但大多数程序员会将消息读作"找不到" surcouche2.dll。异常的最常见原因。这不是问题。

永远不要乱用DLL Hell。将DLL保存在一个单独的目录中并在不同程序之间共享它们的日子很长很久。始终将依赖DLL复制到与需要它们的EXE相同的目录中。使操作系统很容易找到它们。并且避免在找到错误文件时您必须处理的相当大的痛苦。

使用Project + Add Existing Item并选择DLL。将其Copy Local属性设置为True。如果你不喜欢混乱,那么在后期制作活动中使用XCOPY。