- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想要一个从 C++ Windows DLL 导出函数的简单示例。
我想查看 header 、.cpp
文件和 .def
文件(如果绝对需要)。
我希望导出的名称未修饰。我想使用最标准的调用约定(__stdcall
?)。我想使用 __declspec(dllexport)
而不必使用 .def
文件。
例如:
//header
extern "C"
{
__declspec(dllexport) int __stdcall foo(long bar);
}
//cpp
int __stdcall foo(long bar)
{
return 0;
}
我试图避免链接器在名称中添加下划线和/或数字(字节数?)。
我可以不支持使用相同 header 的 dllimport
和 dllexport
。我不需要任何有关导出 C++ 类方法的信息,只需要 C 风格的全局函数。
更新
不包括调用约定(并使用 extern "C"
)为我提供了我喜欢的导出名称,但这意味着什么?我得到的默认调用约定是 pinvoke (.NET)、声明 (vb6) 和 GetProcAddress 所期望的吗? (我猜对于 GetProcAddress
来说,它将取决于调用者创建的函数指针)。
我希望在没有头文件的情况下使用此 DLL,因此我实际上不需要大量花哨的 #defines
来使调用者可以使用该 header 。
我可以接受的答案是我必须使用 *.def
文件。
最佳答案
如果您想要纯 C 导出,请使用 C 项目而不是 C++。 C++ DLL 依赖于所有 C++ 体系(命名空间等)的名称修改。您可以通过进入 C/C++->Advanced 下的项目设置将代码编译为 C,其中有一个选项“Compile As”,它对应于编译器开关/TP 和/TC。
如果您仍然想使用 C++ 编写 lib 的内部结构,但导出一些未损坏的函数以便在 C++ 外部使用,请参阅下面的第二部分。
您真正想要做的是在 header 中定义一个条件宏,该 header 将包含在 DLL 项目中的所有源文件中:
#ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
#else
# define LIBRARY_API __declspec(dllimport)
#endif
然后在要导出的函数上使用LIBRARY_API
:
LIBRARY_API int GetCoolInteger();
在您的库构建项目中创建一个定义LIBRARY_EXPORTS
,这将导致您的函数被导出以用于您的 DLL 构建。
由于 LIBRARY_EXPORTS
不会在使用 DLL 的项目中定义,因此当该项目包含库的头文件时,所有函数都将被导入。
如果您的库是跨平台的,您可以在不在 Windows 上时将 LIBRARY_API 定义为空:
#ifdef _WIN32
# ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
# else
# define LIBRARY_API __declspec(dllimport)
# endif
#elif
# define LIBRARY_API
#endif
使用 dllexport/dllimport 时,不需要使用 DEF 文件,如果使用 DEF 文件,则不需要使用 dllexport/dllimport。这两种方法以不同的方式完成相同的任务,我相信 dllexport/dllimport 是这两种方法中推荐的方法。
如果您需要使用 LoadLibrary 和 GetProcAddress,或者可能从其他语言导入(即来自 .NET 的 PInvoke,或 Python/R 中的 FFI 等),您可以使用 extern "C"
内联您的 dllexport 告诉 C++ 编译器不要破坏名称。由于我们使用 GetProcAddress 而不是 dllimport,因此我们不需要从上面进行 ifdef 舞蹈,只需一个简单的 dllexport:
代码:
#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)
EXTERN_DLL_EXPORT int getEngineVersion() {
return 1;
}
EXTERN_DLL_EXPORT void registerPlugin(Kernel &K) {
K.getGraphicsServer().addGraphicsDriver(
auto_ptr<GraphicsServer::GraphicsDriver>(new OpenGLGraphicsDriver())
);
}
这是使用 Dumpbin/exports 导出的内容:
Dump of file opengl_plugin.dll
File Type: DLL
Section contains the following exports for opengl_plugin.dll
00000000 characteristics
49866068 time date stamp Sun Feb 01 19:54:32 2009
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 0001110E getEngineVersion = @ILT+265(_getEngineVersion)
2 1 00011028 registerPlugin = @ILT+35(_registerPlugin)
所以这段代码工作正常:
m_hDLL = ::LoadLibrary(T"opengl_plugin.dll");
m_pfnGetEngineVersion = reinterpret_cast<fnGetEngineVersion *>(
::GetProcAddress(m_hDLL, "getEngineVersion")
);
m_pfnRegisterPlugin = reinterpret_cast<fnRegisterPlugin *>(
::GetProcAddress(m_hDLL, "registerPlugin")
);
关于winapi - 使用 dllexport 从 DLL 导出函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/538134/
我有一个用 C 编写的可执行文件,其中包含一些我想从 c# 应用程序中使用的函数。我以前写过很多 dll 并且能够通过添加 __declspec(dllexport) 来使用它们中的函数。到函数声明。
我正在使用 RGiesecke DLLExport 库生成一个 C# DLL,它可以从基于 VC6 构建的遗留应用程序中动态加载。它导出方法并从 VC6 代码中调用它们。没问题。但是,只要我尝试为我的
我得到了这个庞大的项目,其中包含许多在 dll 文件中定义的类。我需要提取该项目的一部分并从该部分创建一个新项目。我已经设法通过使用 Visual Studio 中的代码映射找到了一些 dll 文件,
我已根据 MSDN 文档完成所有操作,但我的函数仍未导出。 LINK1 LINK2 LINK3 这是我的(2 个项目,DLL 和从 dll 导入的应用程序),看起来像这样(简短版): DLL 函数.h
我有一个加载 dll 的 exe。我都写了。 我正在导出一个返回 std::wstring 的函数 foo。 它所做的就是说 std::wstring blah = L"rgjwgfw"; ret
考虑一个简单的类,它只包含内联成员函数。例如: template class Point2D { public: typedef Point2D ThisType; typedef
我有我的dll项目 // .h #pragma once #include extern "C" { void __declspec(dllexport) __stdcall sort(int* v
Microsoft 说:“模板不能与使用 __declspec (dllimport) 或 __declspec (dllexport) 声明的函数一起使用。” (link)。 这是什么意思?我可以导
代码: #ifdef BUILD_DLL #define MY_API __declspec(dllexport) #else #define MY_API __declspec(dllimport)
您好,我对 dllexport 有点困惑。例如,当我在类里面使用 __declspec( dllexport ) 时 #define DllExport __declspec( dllexpor
我试图通过导出为 DLL(在 Windows/VS 2010 上)来保护一些 C++ 代码。 在下面的示例中,var 在父类(super class)构造函数中设置,并且调试器显示它肯定设置为引用某物
我现在正在使用 Visual Studio。我有一个经典的宏来标记 dll api 函数和类。我的理解是标记一个类 dllexport 可以使它的功能从其他二进制文件中可见,从而可以使用 dll 提供
我正在创建一个要在 C# 应用程序中使用的 C 包装器库。在我的 .c 中,函数定义如下: __declspec(dllexport) uint8_t aes132h_nonce(struct aes
这个问题可能类似于 DLL Exports: not all my functions are exported但由于那里没有完全回答,我不得不再问一次。我的情况也是因为使用模板和导出整个类略有不同。
现在我分析一些不是我写的旧代码。在 header 中有许多这样的声明: SVPDSDKDLLEXPORT inline C3vec mult(C3vec src, D3DXMATRIX &m); SV
#if COMPILING_DLL #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT __declspec
我只是 c++ 的初学者,对我来说这似乎是不必要的代码膨胀。我知道 dllimport/export 用于共享 dll 功能,但仅使用公共(public)/私有(private)访问器有什么问题? 如
编辑 为了解决这个问题,我将以下内容添加到头文件(的开头): #ifdef GetMessage #undef GetMessage static inline BOOL GetMessage( LP
我正在考虑为名为 SmartDVB 的软件编写插件。它需要我导出以下函数(这是一个 C++ 示例): BOOL RegisterAddOn(UINT iAddOnId, IAddOnInterface
我想使用 dllexport 导出函数。但是我在编译器“错误 C4439:'WrappedC':签名中具有托管类型的函数定义必须具有 __clrcall 调用约定”时遇到错误。 我在头文件 (.h)
我是一名优秀的程序员,十分优秀!