| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1614 人关注过本帖
标题:好吧~~我出问题了,VS2008导出符号,强大的资深的速度来
只看楼主 加入收藏
天使梦魔
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:37
帖 子:564
专家分:2754
注 册:2007-8-29
结帖率:83.33%
收藏
已结贴  问题点数:50 回复次数:10 
好吧~~我出问题了,VS2008导出符号,强大的资深的速度来
PS:如果成功的话可以使用MFC的静态库包含,这也是VS唯一能做的其他不能做的事.
我的需求:第一;动态库必须以动态链接方式连接,opengl,sdl开发里我喜欢的环境是mingw.第二;动态库必须以名字接口引用,如果用序列号我无法更新动态库,原因你们也知道,如果序列号一打乱,意味着我以前开发过的exe无法使用最新版本的动态库.


OK,首先百度无果.
DLL是VS2008开发的,我新建的一个模板,它自带的模板,我写了一个函数,只是一个对话框而已.如果使用序列号方式引用,没什么问题.(见图,我的序列号是第二个)
图片附件: 游客没有浏览图片的权限,请 登录注册


但一旦使用名字字符引用,GetProcAddress返回null(我做过输出了)
图片附件: 游客没有浏览图片的权限,请 登录注册


DLL查看器里查看到的所有导出符号,我像蠢猪一样用过 "void __cdecl rzabout(void)" 也用过 "__cdecl rzabout"
图片附件: 游客没有浏览图片的权限,请 登录注册


extern "C" 我也用过了,用不用导出函数名都一样,而且使用extern "C" __declspec(dllexport)会得到:
error C2159: 指定了一个以上的存储类
我是直接把整个预编译包含进去extern "C"{...预编译头...} 当然用了也这样
搜索更多相关主题的帖子: 百度 对话框 序列号 动态 接口 
2013-08-01 11:29
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:0 
代码打包呢

DO IT YOURSELF !
2013-08-01 11:32
peach5460
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:武汉
等 级:贵宾
威 望:30
帖 子:2780
专家分:6060
注 册:2008-1-28
收藏
得分:5 
围观...

我总觉得授人以鱼不如授人以渔...
可是总有些SB叫嚣着:要么给代码给答案,要么滚蛋...
虽然我知道不要跟SB一般见识,但是我真的没修炼到宠辱不惊...
2013-08-01 11:33
天使梦魔
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:37
帖 子:564
专家分:2754
注 册:2007-8-29
收藏
得分:0 
这也要代码貌似没什么用吧
VS的CPP里是
程序代码:
// RZdream.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "RZdream.h"


// 这是导出变量的一个示例
RZDREAM_API int nRZdream=0;

// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 RZdream.h
/*CRZdream::CRZdream()
{
    return;
}*/

//DLL版权
RZDREAM_API void rzabout(void)
{
    int mymsg;
    mymsg=MessageBox(NULL,L"sdf44",L"555555",MB_YESNO|MB_ICONQUESTION);
    if(mymsg==IDYES)MessageBox(NULL,L"dsfe",L"we234",MB_ICONQUESTION);
}
VS的头文件,去掉extern "C"输出都一样
程序代码:
extern "C"{
#ifdef RZDREAM_EXPORTS
#define RZDREAM_API __declspec(dllexport)
#else
#define RZDREAM_API __declspec(dllimport)
#endif
}

// 此类是从 RZdream.dll 导出的
/*class RZDREAM_API CRZdream {
public:
    CRZdream(void);
    // TODO: 在此添加您的方法。
};*/

extern RZDREAM_API int nRZdream;

RZDREAM_API void rzabout(void);
VS模板的其他代码我不贴了,都是默认的,新建一个就行了




mingw的exe文件
程序代码:
#include <iostream>
#include <windows.h>

using namespace std;

int main (int argc, char *argv[])
{
  HINSTANCE hinstdll=LoadLibrary("RZdream.dll");
  if(hinstdll==0)cout<<"no dll\n";
  FARPROC test=GetProcAddress(hinstdll,"rzabout");//不能使用名字字符,只能使用序列号
  if(test==0)cout<<"no in\n";
  test();
  FreeLibrary(hinstdll);
  cin.get();
}

2013-08-01 11:39
天使梦魔
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:37
帖 子:564
专家分:2754
注 册:2007-8-29
收藏
得分:0 
后续整个美好设想全被这个2008的内核编译方式给毁了
我现在歇菜了
2013-08-01 11:40
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:0 
以下是引用天使梦魔在2013-8-1 11:39:09的发言:

 
int main (int argc, char *argv[])
{
  HINSTANCE hinstdll=LoadLibrary("RZdream.dll");
  if(hinstdll==0)cout<<"no dll\n";
  FARPROC test=GetProcAddress(hinstdll,"rzabout");//不能使用名字字符,只能使用序列号
  if(test==0)cout<<"no in\n";
  test();
  FreeLibrary(hinstdll);
  cin.get();
}
你的意思是这个dll中地函数 你无法使用????

DO IT YOURSELF !
2013-08-01 11:58
天使梦魔
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:37
帖 子:564
专家分:2754
注 册:2007-8-29
收藏
得分:0 
exe启动后,代码被存放到内存,有一个代码区域.
exe伴随dll启动后,exe将dll代码一起映射到内部,成为exe的一部分.
唯一的区别是exe无法直接使用dll名称呼叫,因为exe代码内部没有这些声明方法.
做法就两种,一种是加入dll编译出来的lib,这个静态库里包含对打dll的使用方法,exe只要声明一个名字就可以直接在lib里找方法.还有一种是exe映射"在自己身体里但不是自己的肉"的地址,函数有了地址就可以启动

用序列号方式GetProcAddress(hinstdll,MAKEINTRESOURCE(2))可以获得DLL内部这个函数的地址,有了这个地址就可以使用这个函数.
但如果使用名字方式GetProcAddress(hinstdll,"rzabout")就怎么也无法获得这个函数在DLL的内部地址,永远都是0.很明显错误出在名字字符上,但DLL查看器查看到的导出符号都试过了,也连接不上.
2013-08-01 12:17
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9008
专家分:53957
注 册:2011-1-18
收藏
得分:40 
主要问题就是,你不知道dll中导出名字到底是啥。可以用 depends(网上有下载,Google一下)查看一下就知道了

通过 extern "C" 及 __stdcall 等控制的链接名规则我就不说了
就说说最简单的吧,你可以自己写个def来给出清晰的名字,比如
LIBRARY win32dll
EXPORTS
    AAA @1 DATA
    GetAAA @2
    SetAAA @3
打开工程属性页 configuration properties->Linker->Input->Module Definition File输入def文件名

顺便你也可以看到,可以用@来指定顺序,即你说的“如果用序列号我无法更新动态库,原因你们也知道,如果序列号一打乱,意味着我以前开发过的exe无法使用最新版本的动态库.”不成立。
2013-08-01 12:56
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:5 
程序代码:
#include <iostream>
#include <windows.h>

using namespace std;

int main (int argc, char *argv[])
{
    int tmp=0;
    HINSTANCE hinstdll=LoadLibrary(L"d:\\tdll.dll");
    if(hinstdll==0) cout<<"no dll\n";
    FARPROC test1=GetProcAddress(hinstdll,"_Max@8");
    if(test1==0)
    {
    }
    else
    {
        _asm
        {
            push 5;
            push 8;
            call test1;   //这是一个求2个数中地最大值得函数
            mov tmp,eax
        }
        cout<<tmp<<endl;
    }

    FreeLibrary(hinstdll);
    return 0;
}

我的测试能够成功

DLL中代码如下:
程序代码:
extern "C" _declspec(dllexport) int _stdcall Max(int a, int b)
{

 if(a>=b)return a;

 else

 return b;
} 


DO IT YOURSELF !
2013-08-01 13:01
天使梦魔
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:37
帖 子:564
专家分:2754
注 册:2007-8-29
收藏
得分:0 
if(test1==0)
    {
    }
如果取不到地址反而什么都不做
else是取到地址后的做法


我突然想到了,vs2005以上版本全部变成宽字符了.
2013-08-01 14:58
快速回复:好吧~~我出问题了,VS2008导出符号,强大的资深的速度来
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014754 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved