例如,我有name1.dll
方法:
void func1(int)
int func2(bool, char)
和name2.dll
,方法为:
std::string func1()
bool func2(int, int, int)
为了使用它们,我想使用以下语法分别获取一些生成的类及其对象
DECLARE_WRAPPER(
Wrapper1,
DECLARE_METHOD(func1, void(int))
DECLARE_METHOD(func2, int(bool, char))
)
然后呢
DECLARE_WRAPPER(
Wrapper2,
DECLARE_METHOD(func1, std::string())
DECLARE_METHOD(func2, bool(int, int, int))
)
然后像这样使用:
Wrapper1 w1("name1.dll");
w1 func1(6);
w1.func2(false, 'c');
Wrapper w2("name2.dll");
w2.func1();
w2.func2(6, 5, 7)
到目前为止,我的C++代码如下:
#include <iostream>
#include <string>
#include <windows.h>
#define DECLARE_METHOD(name, ret, ...) \
ret name(__VA_ARGS__) { \
FARPROC proc = GetProcAddress(m_hDll, #name); \
if (proc == nullptr) { \
throw std::runtime_error("Function not found"); \
} \
va_list args; \
va_start(args, __VA_ARGS__); \
ret result = reinterpret_cast<ret(__cdecl*)(__VA_ARGS__)>(proc)(__VA_ARGS__); \
va_end(args); \
return result; \
}
#define DECLARE_WRAPPER(wrapperName, ...) \
class wrapperName { \
public: \
wrapperName(const std::string& dllPath) : m_hDll(nullptr) { \
m_hDll = LoadLibraryA(dllPath.c_str()); \
} \
~wrapperName() { \
if (m_hDll) { \
FreeLibrary(m_hDll); \
} \
} \
__VA_ARGS__ \
private: \
HMODULE m_hDll; \
};
DECLARE_WRAPPER(
Wrapper1,
DECLARE_METHOD(func1, void, int)
DECLARE_METHOD(func2, int, bool, char)
);
DECLARE_WRAPPER(
Wrapper2,
DECLARE_METHOD(func1, std::string)
DECLARE_METHOD(func2, bool, int, int, int)
);
int main() {
const std::string dllPath1 = "name1.dll";
const std::string dllPath2 = "name2.dll";
Wrapper1 w1(dllPath1);
w1.func1(6);
int res = w1.func2(false, 'c');
std::cout << "Wrapper1::func2 returned " << res << std::endl;
Wrapper2 w2(dllPath2);
std::string str = w2.func1();
std::cout << "Wrapper2::func1 returned " << str << std::endl;
bool b = w2.func2(6, 5, 7);
std::cout << "Wrapper2::func2 returned " << b << std::endl;
return 0;
}
但是我有错误,我不能使它工作。如何修复此代码?或者,我试图实现一些不能在C++中完成的事情?我可以使用的当前版本是C++17
。
2条答案
按热度按时间zxlwwiss1#
我不认为你可以像现在这样在
DECLARE_WRAPPER()
的内部使用DECLARE_METHOD()
。你可能需要将DECLARE_WRAPPER()
分解成单独的宏,这样你就可以在它们之间使用DECLARE_METHOD()
s。然而,
DECLARE_METHOD()
本身肯定不会像你写的那样工作。它不能使用__VA_ARGS__
来声明方法参数和调用加载的proc()
。而且,它根本无法将__VA_ARGS__
传递到va_start()
(这并不重要,因为你没有使用args
)。你应该使用C++风格的可变参数模板,而不是C风格的可变参数宏。试试这样的方法:
Online Demo
顺便说一下,
Wrapper2::func1()
通过DLL边界传递std::string
是不安全的。如果DLL函数返回一个char*
,你想转换成std::string
,那么你的DECLARE_METHOD()
宏将不得不考虑这一点,通过单独的参数来分别指定两个返回类型。例如:mutmk8jj2#
也许这会对某些人有用,所以我正在写我的“最终”表格。是的,有很多事情要做,但这里有一个框架,几乎适合我:
不要严格判断。理想情况下,如果可以突出显示所用方法的所有参数,那将是非常方便和良好的。