VC++导出具有命名空间的函数

    • 问题现象
    • 原因分析
    • 解决的方法

1 问题现象

导出具有命名空间的函数和类。源码例如以下:

头文件MiniMFC.h

namespace MiniMFC
{
    __declspec(dllexport) void f();
    class __declspec(dllexport) MyClass
    {
    public:
        void Mf();
    };
}

实现文件MiniMFC.cpp

#include "stdafx.h"
#include <iostream>
using namespace std;

#include "MiniMFC.h"
using namespace MiniMFC;

void MyClass::Mf()
{
    cout << "I‘m MiniMFC::MyClass::Mf() from DLL" << endl;
}

void f()
{
    cout << "I‘m MiniMFC::f() from DLL" << endl;
}

终于生成的dll文件里并没有导出void f()函数。

使用dependency Walker查看结果为:

[email protected]@@[email protected]@@Z

[email protected]@[email protected]@QAEXXZ

可见仅仅导出了类的构造函数和成员函数。全局函数f()没有导出。

2 原因分析

实现文件里的函数f()的定义并未使用名字空间MiniMFC,所以仅仅得到了全局名字空间的一个名为f的函数。而头文件里声明的那个MiniMFC名字空间中名为f的函数并没有实现代码。

我们把.cpp文件里的函数定义改为例如以下:

 __declspec(dllexport) void f()
{
    cout << "I‘m MiniMFC::f() from DLL" << endl;
}

然后又一次编译。使用Dependency Walker能够看出,这次dll确实导出了名为f的函数。可是它是全局空间的,不是MiniMFC名字空间里的。

??

[email protected]@@[email protected]@@Z

?

[email protected]@[email protected]@QAEXXZ

?

[email protected]@YAXXZ

3 解决的方法

知道了原因。解决起来很easy。仅仅须要在实现文件里f()的定义中使用MiniMFC名字空间进行限定。

例如以下所看到的:

void MiniMFC::f()
{
    cout << "I‘m MiniMFC::f() from DLL" << endl;
}

又一次编译后。这次得到了正确的结果:

?

[email protected]@@[email protected]@@Z

[email protected]@[email protected]@QAEXXZ

[email protected]@@YAXXZ

时间: 2024-10-27 21:48:02

VC++导出具有命名空间的函数的相关文章

VC和LUA混合开发之VC程序调用Lua脚本函数

http://www.cnblogs.com/clever101/archive/2010/04/14/1712207.html 作者:朱金灿 来源:http://www.cnblogs.com/clever101/ Lua语言以其卓越的可扩展性.简单.高效率和与平台无关性在游戏领域得到广泛应用.今天花了一些时间学习VC和Lua如何混合开发,编写了一个小例程,和大家分享一下这方面的经验. 首先在http://www.lua.org/ftp/下载Lua的最新版本:lua-5.1.4.然后用VS C

VC和gcc在保证函数static变量线程安全性上的区别

VC和gcc不同,不能保证静态变量的线程安全性.这就给我们的程序带来了很大的安全隐患和诸多不便.这一点应该引起我们的重视!尤其是在构造函数耗时比较长的时候,很可能给程序带来意想不到的结果.本文从测试代码开始,逐步分析原理,最后给出解决方案. 多线程状态下,VC不能保证在使用函数的静态变量的时候,它的构造函数已经被执行完毕,下面是一段测试代码: class TestStatic { public: TestStatic() { Sleep(1000*10); m_num = 999; } publ

VC中BeginWaitCursor()和EndWaitCursor()函数

BeginWaitCursor()是CCmdTarget类的函数,    函数原型:void   BeginWaitCursor();    功能简介:本函数用于显示沙漏光标(通常在命令执行较长时采用).    框架调用本函数显示沙漏光标,告诉用户系统忙.    在不是处理单个消息时,    BeginWaitCursor()可能不像其它函数那样有效,例如    OnSetCursor()的处理也能改变光标形状.    调用函数EndWaitCursor可以恢复此前的光标. VC中BeginWa

MySQL mysqldump 导入/导出 结构&amp;数据&amp;存储过程&amp;函数&amp;事件&amp;触发器

———————————————-库操作———————————————-1.①导出一个库结构 mysqldump -d dbname -u root -p > xxx.sql ②导出多个库结构 mysqldump -d -B dbname1 dbname2 -u root -p > xxx.sql 2.①导出一个库数据 mysqldump -t dbname -u root -p > xxx.sql ②导出多个库数据 mysqldump -t -B dbname1 dbname2 -u r

201506231015_《Javascript权威指南(第六版)——作为命名空间的函数、闭包、 》(P181-193)

1. 作为命名空间的函数. 形如: var someFn = (function(){var a = 0;return function f(){// ...};}()); 2. 闭包. 闭包内无法直接访问外部函数的参数,除非将外部的实参列给一个变量存储以来.例如:var outerArguments = arguments; 3. 函数的属性,方法,构造函数 a.       arguments.length;  (期望传入的实参个数) arguments.callee.lenth;(实际传入

《JS权威指南学习总结--8.5 作为命名空间的函数》

内容要点:    函数作用域的概念:在函数中声明的变量在整个函数体内都是可见的(包括在嵌套的函数中),在函数的外部是不可见的.不在任何函数内声明的变量是全局变量,在整个JS程序中都是可见的. 在JS中无法声明只在一个代码块内可见的变量的.(在客户端JS中这种说法不完全正确,比如,在有些JS的扩展中就可以使用let来声明语句块内的变量) 基于这个原因,我们常常简单地定义一个函数用做临时的命名空间,在这个命名空间内定义的变量是都不会污染到全局命名空间. 比如,假设你写了一段JS模块代码,这段代码将要

JavaScript命名空间、函数参数类型重载的实现

突然心血来潮写的东西,可以考虑在func({arg1: xxx, arg2: xxx})不适用的情况下使用. <!DOCTYPE html> <html lang="zh"> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <title>命名空间.参数类型重载</title>

【C/C++学院】0813-C与CPP不同以及命名空间简介/函数重载与函数默认参数/泛型auto/Newdelete

C与CPP不同以及命名空间简介 命名空间在软件设计中的作用就是为了实现迭代式开发. 命名空间的别名 #include <iostream> namespace runrunrunrun { int a(10); char *str("gogogo"); namespace run //命名空间的嵌套 { int a(9); } } namespace runrunrunrun //命名空间的拓展 { int y(5); //int a(15);重定义错误 } namespa

DLL中导出ANSI和UNICODE函数

模仿window中的DLL导出ANSI和UNICODE版本的函数,使用UNICODE宏来控制使用哪个版本: 在函数实际的执行代码UNICODE版本中,在ANSI函数的版本中只做参数的转换,及ANSI字符串转UNICODE字符串,然后调用UNICODE版本的函数.  0.DLL头文件 #include <Windows.h> #ifndef _ICAL_H_ #define _ICAL_H_ #ifdef DLL_EXPORT_IMP #define DLL_EXPORT extern &quo