DllImport特性为什么没能找到我自定义的dll呢?

skktuer skktuer 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
我新建了一个solution,首先建立一个VC的project,是dll的,名字叫做MyLib,里面导出函数:

MYLIB_API void PrintMsg(const char*msg)
{
printf("msg=%s\n",msg);
}

然后在同一个工程当中,我新建一个.net的控制台程序project,主程序如下:

class Program
{
[DllImport("MyLib.dll"]
static extern void PrintMsg(string s);

[STAThread]
static void Main(string[] args)
{
PrintMsg("abc");
}
}

编译没有问题,运行的时候会报错
未经处理的异常: System.DllNotFoundException: 无法加载 DLL“MyLib.dll”: 找不到
指定的模块。 (异常来自 HRESULT:0x8007007E)。
在 UseCom.Program.PrintMsg(String s)
在 UseCom.Program.Main(String[] args) 位置 d:\Users\a\Documents\Visual Studio
2012\Projects\ATLProject1\UseCom\Program.cs:行号 48
请按任意键继续. . .

奇怪了,我都是在同一个solution里面编译的,怎么就找不到dll呢? 于是我找到MyLib.dll存放的地方,把绝对路径写到DllImport这个Attribut里面,然后再编译运行:

[DllImport(@"D:\Users\a\Documents\Visual Studio 2012\Projects\ATLProject1\Debug\MyLib.dll")]

未经处理的异常: System.EntryPointNotFoundException: 无法在 DLL“D:\Users\a\Docu
ments\Visual Studio 2012\Projects\ATLProject1\Debug\MyLib.dll”中找到名为“Print
Msg”的入口点。
在 UseCom.Program.PrintMsg(String s)
在 UseCom.Program.Main(String[] args) 位置 d:\Users\a\Documents\Visual Studio
2012\Projects\ATLProject1\UseCom\Program.cs:行号 48
请按任意键继续. . .

行号48就是PrintMsg("abc")这句。我用的是VS2012。哪位高人帮我解答一下?
...全文

相关推荐

c#的dllimport使用方法详解

DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息

weixin_38537315

C#调用C/C++编译生成的dll库

本文详细介绍了如何在C#中调用C/C++编译生成的.dll库。首先,需要使用DllImport特性指定.dll文件并转换函数的返回类型和参数。然后,通过创建C++项目生成DLL文件,最后在C#项目中引入DLL并实现调用,确保DLL文件放置在正确的位置。

绝版公子文少

C# 如何调用 Delphi 编写的 DLL 方法

本文介绍了如何使用C#的DllImport特性来调用Delphi编写的DLL方法。通过设置DllImport的参数,如dllName、CallingConvention、CharSet等,可以实现对非托管DLL函数的调用。详细解释了DllImport的使用方法和注意事项,并提供了示例代码。

Arthur

C#调用c++dll的两种方法(静态方法和动态方法)

本文介绍了C#调用C++ DLL的两种方法。首先说明了C#项目创建步骤,需引入System.Runtime.InteropServices命名空间。接着阐述静态调用方法,通过DllImport特性实现。最后介绍动态调用方法,好处是DLL可随意放置,还给出了加载和释放DLL的代码示例。

AI+嵌入式在路上

C# DllImport的用法

大家在实际工作学习C#的时候,可能会问:为什么我们要为一些已经存在的功能(比如Windows中的一些功能,C++中已经编写好的一些方法)要重新编写代码,C#有没有方法可以直接都用这些原本已经存在的功能呢?答案是肯定的,大家可以通过C#中的DllImport直接调用这些功能。 DllImport所在的名字空间 using System.Runtime.InteropServices; MSDN中对DllImportAttribute的解释是这样的:可将该属性应用于方法。DllImportAttribute 属性提供对从非托管 DLL 导出的函数进行调用所必需的信息。作为最低要求,必须提供包含入口点的 DLL 的名称。 DllImport 属性定义如下: namespace System.Runtime.InteropServices {   [AttributeUsage(AttributeTargets.Method)]   public class DllImportAttribute: System.Attribute   {    public DllImportAttribute(string dllName) {...}    public CallingConvention CallingConvention;    public CharSet CharSet;    public string EntryPoint;    public bool ExactSpelling;    public bool PreserveSig;    public bool SetLastError;    public string Value { get {...} }   } }   说明:   1、DllImport只能放置在方法声明上。   2、DllImport具有单个定位参数:指定包含被导入方法的 dll 名称的 dllName 参数。   3、DllImport具有五个命名参数:    a、CallingConvention 参数指示入口点的调用约定。如果未指定 CallingConvention,则使用默认值 CallingConvention.Winapi。    b、CharSet 参数指示用在入口点中的字符集。如果未指定 CharSet,则使用默认值 CharSet.Auto。    c、EntryPoint 参数给出 dll 中入口点的名称。如果未指定 EntryPoint,则使用方法本身的名称。    d、ExactSpelling 参数指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配。如果未指定 ExactSpelling,则使用默认值 false。    e、PreserveSig 参数指示方法的签名应当被保留还是被转换。当签名被转换时,它被转换为一个具有 HRESULT 返回值和该返回值的一个名为 retval 的附加输出参数的签名。如果未指定 PreserveSig,则使用默认值 true。    f、SetLastError 参数指示方法是否保留 Win32"上一错误"。如果未指定 SetLastError,则使用默认值 false。   4、它是一次性属性类。   5、此外,用 DllImport 属性修饰的方法必须具有 extern 修饰符。

dishkk
评论 3
收藏 已收藏
分享
返回顶部
skktuer
C# 111,128 成员 642,536 内容