首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

_cdecl 和 _stdcall 新有关问题 再开一帖

2012-04-08 
__cdecl和_stdcall新问题再开一帖貌似C#不理这些约定 __stdcall __cdecl我用C++写的动态链接库导出的__std

__cdecl 和 _stdcall 新问题 再开一帖
貌似C#不理这些约定 __stdcall __cdecl

我用C++写的动态链接库 导出的__stdcall 函数 和__cdecl函数

在C#中静态导入后 都可正确调用 C#或者.NET怎么做到的呢

[解决办法]
在C#中静态导入……C#那是静态导入么?那是只有运行时才会看出异常来……
[解决办法]
并不知道 .net 平台是如何处理“非托管代码”与“托管代码”之间的映射的——但调用成功,是通过这种映射方式。但从.net程序去调用“非托管”函数本身——就是你所指的C++函数——就不可能存在“静态导入”这么一回事儿。那是运行期的动态行为。

你在编写.net 代码的时候,你声明的只是一个接口声明,至于源C++非托管函数是否真实存在,.net根本不管,在编译时是查不出来的,能查到的,只是你在.net代码中标明的EntryPoint 而已。
[解决办法]
UP..

[解决办法]
c#代码中调用c/c++的dll最终是还是.net的虚拟机和dll交互的,.net虚拟机是以c或者c++写成的,所以.net虚拟机可成功
使用用dll,并可以提供dll一个c#的接口。所以c#使用dll,com啥的都是基于强大的vm的基础上的。
[解决办法]
MARK
[解决办法]
一般对于C#等其他语言调用C++的dll,最好做成Windows 标准DLL,也就是用_stdcall调用约定方式的
[解决办法]
学习...
[解决办法]
学习
[解决办法]
haoa
[解决办法]
mark
[解决办法]
好极了
[解决办法]
ddddddddddddddddddddddddddd
[解决办法]
学习下
[解决办法]
个人认为,dll被vm加载时,vm有能力来解析dll中二进制的数据,dll使用时最终要映射到内存地址空间里。vm是微软出的虚拟机
所以vm可以正确的解析pe文件,dll等pe文件中存在关于函数的相关信息,所以一切是vm把函数成功解析,并转化成和c#一致的代码

总起来说,vm和操作系统有同样的能力加载和解析dll等pe文件,按照pe文件的组织方式,获取到相关函数信息,并把这些信息
成功转化成被c#正确处理的相关信息。
最终应该是从.net及其vm实现上寻找原因了。

一家之言,高手见笑了。
[解决办法]
up ...............
[解决办法]
UP

[解决办法]
首先应该明白__stdcall和__cdecl是干什么用的。他们的区别是函数参数入栈的顺序,如果函数没有参数,则他们没有区别
[解决办法]
UP!
[解决办法]
绝对是技术贴,顶一下楼主

__stdcall与__cdecl在C/C++写成的DLL中是必须的

但是在C#中,对应的关键字已经修改成DLLIMPORT,在不同的.NET FRAMEWORK中,DLLIMPORT对调用接口的参数排序有不同的处理方式

楼主使用的哪一个版本的.NET FRAMEWORK呢?
[解决办法]
mark....
[解决办法]
写成标准Win32 DLL可以方便使用。
[解决办法]
mark
[解决办法]

探讨
.....并转化成和c#一致的代码.....并把这些信息成功转化成被c#正确处理的相关信息。

[解决办法]
关注 UP!~
[解决办法]


友情UP
[解决办法]

探讨
引用:
.....并转化成和c#一致的代码.....并把这些信息成功转化成被c#正确处理的相关信息。


不对,调用者和DLL在不同的内存空间各自执行各自的PROCEDURE这一点上,无论是谁来进行调用都是如此。不会进行互相转化,更别提转“代码”了。

DLL 编译完成后就是一堆二进制机器码,不会转成C#代码……再说C#被BUILD后是一堆IL,是.net下的汇编。你这么来解释有点……

关于编译期的行为,我在此贴…

[解决办法]
标准win32 dll是汇编级的复用,所有程序最终都是汇编级执行的,所以标准win32 dll能跨语言被调用。
[解决办法]
帮顶~
[解决办法]

以上个人见解,说了这么多,有点迷糊了,主要还是自己功力太浅了。
[解决办法]
vm解析dll后,生成能够正确跳转到dll执行的IL就足够了。dll运行应该是os直接运行,而非vm。
[解决办法]
很复杂的讨论。能用就好了,真正的原因估计CSDN中是没有人能够说清楚的
[解决办法]
__cdecl 由调用者清栈,__stdcall 由函数清栈 ,没有参数,两者表现是一样的

C#调用本地的DLL通过平台调用,所谓平台调用完成
1、查找包含该函数的 DLL。
2、将该 DLL 加载到内存中。
3、查找函数在内存中的地址并将其参数推到堆栈上,以封送所需的数据。
简单的说它类似于c++中Loadlibrary来加载,然后用GetProcAddress取得函数,再进行调用

实际上因为一般WinAPI采用的中__stdcall,因此平台调用默认采用这种方式来进行,但是可以通过
指定DllImportAttribute的成员 CallingConvention 值为以下几种
Cdecl 
FastCall 
StdCall 
ThisCall 
Winapi 


[解决办法]
探讨
C/C++ code

extern "C" void __declspec(dllexport) __cdecl SetHook();
extern "C" bool __declspec(dllexport) __cdecl UnHook();


LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam);
void __cdecl SetHook()
{
SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,dllHinstance,0);
}

bool __cdecl UnHook()
{
return UnhookWindowsHookEx(hhk);
}

LRESULT CALLBACK KeyboardProc(…

[解决办法]
taihao

太好了


着呢更想知道
谢谢分享


[解决办法]
学习!!

热点排行