(在线等)C#调用C++的dll

dongdong19871024 2010-01-31 07:16:52
int __stdcall HS_DES(int op, char *key, char *inblock, char *outblock, int len);

我要在C#中使用C++中的一个方法,封装在 XX.dll中。
如何调用??

我是这样写的
using System.Runtime.InteropServices;

[DllImport("XX.dll", EntryPoint = "HS_DES")]
public static extern string HS_DES(int op, string key, string inblock, string outblock, int len);

提示无法加载,我不清楚C++中的指针类型如何在C#中表示。

怎么写才是正确的 大家帮下忙。。。
...全文
216 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
diy2005 2011-10-24
  • 打赏
  • 举报
回复
缺少依赖项吧
diy2005 2011-10-24
  • 打赏
  • 举报
回复
依赖项吧
rizher 2010-01-31
  • 打赏
  • 举报
回复
顶一下
soaringbird 2010-01-31
  • 打赏
  • 举报
回复
无法加载是找不到dll,可能路径不对。
找不到入口点是入口点写错了。
内存错误可能是参数类型不对
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
兄弟,找到一篇针对你情况的文章:
下面有原文地址,摘目部分如下:
(真是天外有天啊,我怎么没想到呢?)

[C#动态调用C++编写的DLL函数]



动态加载DLL需要使用Windows API函数:LoadLibrary、GetProcAddress以及FreeLibrary。我们可以使用DllImport在C#中使用这三个函数。

[DllImport("Kernel32")]
public static extern int GetProcAddress(int handle, String funcname);

[DllImport("Kernel32")]
public static extern int LoadLibrary(String funcname);

[DllImport("Kernel32")]
public static extern int FreeLibrary(int handle);

当我们在C++中动态调用Dll中的函数时,我们一般的方法是:
假设DLL中有一个导出函数,函数原型如下:
BOOL __stdcall foo(Object &object, LPVOID lpReserved);

1、首先定义相应的函数指针:
typedef BOOL (__stdcall *PFOO)(Object &object, LPVOID lpReserved);

2、调用LoadLibrary加载dll:
HINSTANCE hInst = ::LoadLibraryW(dllFileName);

3、调用GetProcAddress函数获取要调用函数的地址:
PFOO foo = (PFOO)GetProcAddress(hInst,"foo");
if(foo == NULL)
{
FreeLibrary(hInst);
return false;
}

4、调用foo函数:
BOOL bRet = foo(object,(LPVOID)NULL);

5、使用完后应释放DLL:
FreeLibrary(hInst);

那么在C#中应该怎么做呢?方法基本上一样,我们使用委托来代替C++的函数指针,通过.NET Framework 2.0新增的函数GetDelegateForFunctionPointer来得到一个委托的实例:

下面封装了一个类,通过该类我们就可以在C#中动态调用Dll中的函数了:

public class DLLWrapper
{
///<summary>
/// API LoadLibrary
///</summary>
[DllImport("Kernel32")]
public static extern int LoadLibrary(String funcname);

///<summary>
/// API GetProcAddress
///</summary>
[DllImport("Kernel32")]
public static extern int GetProcAddress(int handle, String funcname);

///<summary>
/// API FreeLibrary
///</summary>
[DllImport("Kernel32")]
public static extern int FreeLibrary(int handle);

///<summary>
///通过非托管函数名转换为对应的委托, by jingzhongrong
///</summary>
///<param name="dllModule">通过LoadLibrary获得的DLL句柄</param>
///<param name="functionName">非托管函数名</param>
///<param name="t">对应的委托类型</param>
///<returns>委托实例,可强制转换为适当的委托类型</returns>
public static Delegate GetFunctionAddress(int dllModule, string functionName, Type t)
{
int address = GetProcAddress(dllModule, functionName);
if (address == 0)
return null;
else
return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
}

///<summary>
///将表示函数地址的IntPtr实例转换成对应的委托, by jingzhongrong
///</summary>
public static Delegate GetDelegateFromIntPtr(IntPtr address, Type t)
{
if (address == IntPtr.Zero)
return null;
else
return Marshal.GetDelegateForFunctionPointer(address, t);
}

url=http://www.pcstu.com/program/Asp_net/jq/20100113/66287.html]原文地址[/url]
mjp1234airen4385 2010-01-31
  • 打赏
  • 举报
回复
[DllImport("HsDes.dll")]
public static extern int HS_DES(int op, StringBuilder key, StringBuilder inblock, out StringBuilder outblock, int len);

还是不行的话:
public static extern int HS_DES(int op, byte[] key, byte[] inblock, out byte[] outblock, int len);
duck530 2010-01-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 yangglemu 的回复:]
我简单试了一下,成功:
新建一个C++工程,选择win32项目,再选择Dll,命名为Test,在Test.cpp文件中写入:
C/C++ codeextern"C" __declspec(dllexport)int GetData()
{return13;
}
编译,生成一个Test.dll文件
C#中调用:
新建一个控制台程序工程,将Test.dll文件拷到工程的Bin目录下,然后在Main函数中写如下代码:

C# codeclass Program
{
[DllImport("Test.dll")]externstaticint GetData();staticvoid Main(string[] args)
{int x= GetData();
Console.WriteLine(x);
}
}
函数返回13,结果正确

你如果有大量以前的C/C++库要能在C#中调用,一般有如下方法解决:改写为COM/用C#重新写/包装成外部能调用的Dll(就是DLL中函数前有extern "C" __declspec(dllexport)声明的方法),最后一种方法是最省事而且不用更改函数逻辑的
你可以看一下你的C++DLL函数原文件有否声明为extern "C" __declspec(dllexport)供外部调用,也可以用其中一个库的某个函数加上extern "C" __declspec(dllexport)语句试试在C#中能否调用
[/Quote]
  • 打赏
  • 举报
回复
有没有原文件,有原文件就好办了,没有原文件,但知道函数功能也能办,麻烦点
前者:修改原文件,在函数名前加上extern "C" __declspec(dllexport),这样保存函数名在编译的时候不乱
后者:自己新建一个C++Dll工程,在其中操作原来的Dll函数,当然现在的C++DLL主CPP文件中函数前一定要加extern "C" __declspec(dllexport)哟,不过这样一来就有两个Dll了,间接调用,麻烦

你的情况适用后者(没有原文件,但有头文件可以知道函数功能)
dongdong19871024 2010-01-31
  • 打赏
  • 举报
回复
在添加引用的时候会提示“确保可访问并且是有效的程序集或COM组件”

使用时报错为 未能加载
dongdong19871024 2010-01-31
  • 打赏
  • 举报
回复
不知道怎么用

目前我只有三个文件 *.DLL *.h *.lib
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 liyoubaidu 的回复:]
像extern "C" __declspec(dllexport)这些,好像是指定编译方式的,不同的编译方式C#里的特性里有不同的写法。
[/Quote]
C++编译器在生成函数名的时候会根据自己的规则重新命名函数,比如 GetData()可能会变成GetData_int()
这样你在C#中调用的时候用GetData能行吗? 用extern "C" 就是提醒编译器按照C风格命名约定来生成,这样GetData()还是GetData()!
我估计楼主的问题就出在这里
liyoubaidu 2010-01-31
  • 打赏
  • 举报
回复
像extern "C" __declspec(dllexport)这些,好像是指定编译方式的,不同的编译方式C#里的特性里有不同的写法。
  • 打赏
  • 举报
回复
我简单试了一下,成功:
新建一个C++工程,选择win32项目,再选择Dll,命名为Test,在Test.cpp文件中写入:
extern "C" __declspec(dllexport) int GetData()
{
return 13;
}

编译,生成一个Test.dll文件
C#中调用:
新建一个控制台程序工程,将Test.dll文件拷到工程的Bin目录下,然后在Main函数中写如下代码:

class Program
{
[DllImport("Test.dll")]
extern static int GetData();
static void Main(string[] args)
{
int x = GetData();
Console.WriteLine(x);
}
}

函数返回13,结果正确

你如果有大量以前的C/C++库要能在C#中调用,一般有如下方法解决:改写为COM/用C#重新写/包装成外部能调用的Dll(就是DLL中函数前有extern "C" __declspec(dllexport)声明的方法),最后一种方法是最省事而且不用更改函数逻辑的
你可以看一下你的C++DLL函数原文件有否声明为extern "C" __declspec(dllexport)供外部调用,也可以用其中一个库的某个函数加上extern "C" __declspec(dllexport)语句试试在C#中能否调用
dongdong19871024 2010-01-31
  • 打赏
  • 举报
回复
我将那三个文件放在当前目录下和Bin目录下了 还需要做什么???
liyoubaidu 2010-01-31
  • 打赏
  • 举报
回复
路径对吗?
dongdong19871024 2010-01-31
  • 打赏
  • 举报
回复
我对C++不太了解,给我的东西里面有 *.DLL *.h *.lib

.h中的方法int __stdcall HS_DES(int op, char *key, char *inblock, char *outblock, int len);

我要在C#中调用这个方法。

我在网上查了好几种方法,结果都是报这个错误 问题是出在哪了???

麻烦详细点 ,对C++不太懂
  • 打赏
  • 举报
回复
如:

extern "C" __declspec(dllexport) int myMethod()
{
return 10;
}


你试着弄个如上最简单的函数调用试试,如果在C#中返回结果正确....
dongdong19871024 2010-01-31
  • 打赏
  • 举报
回复
这个不是表示的是被C语言调用吗??我在C#中应该如何写
  • 打赏
  • 举报
回复
extern "C" __declspec(dllexport)在函数前或者Dll头文件声明这样的语句没有?
你的情况是Dll没有加载,不是参数的问题
加载更多回复(4)

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧