我的任务是使用 C++ 与来自第三方公司的 dll 进行交互。
dll包自带:
- dll本身
- 示例 Java 实现 - 由使用 SWIG 工具生成的 java 包装器(库)和 java 源文件组成
- 说明所有公共(public)数据类型、枚举和成员函数的文档。
我的另一位同事正在使用 Java(基于包中的示例)与 dll 交互,而我被要求使用 C++。 Java 示例看起来很直接......只需导入包装器并实例化文档中描述的任何类......
关于 dll 的更多信息:
- 根据文档,它说 dll 是使用 C++ 编写的
- 从 hexdump 中可以看出,它是使用 VC90(VS C++ 2008 对吧?)和 Dinkumware 的一些东西编译的。
- 从 depends.exe 输出来看,这些函数似乎被包装在 JNI 下。例如:
_Java_mas_com_oa_rollings_as_apiJNI_Server_1disconnect@20
我的困境:
- dll 公司没有更改 dll 中的任何内容,也没有提供任何其他信息。
- 如何使用 dll 中类中的成员函数?
- 我做了一些简单的 LoadLibrary() 和 GetProcAddress 并设法获取了公共(public)成员函数的地址。
- 但我不知道如何使用具有在 dll 中定义的数据类型参数的函数。例如:
从文档中,成员函数定义为:
void Server::connect(const StringArray, const KeyValueMap) throw(std::invalid_argument,std::out_of_range)
typedef std::map Server::KeyValueMap
typedef std::vector Server::StringArray
我如何在 C++ 中调用该函数。我的编译器 (VS 2005) 中的 std::map 和 std::vector 具有与 dll 中的列表不同的函数。例如,从 depends.exe 输出:
- std::map//KeyValueMap - del, empty, get, has_1key,set
- std::vector//StringArray - add、capacity、clear、get、isEMPTY、reserve、set、size
关于我应该如何解决这个问题的任何建议/策略?是否可以像Java示例一样简单地实例化类?
最佳答案
如果您尝试使用 VS 2005 尝试与使用 VS2008 构建的 DLL 进行交互,除非您可以使用纯 C 接口(interface),否则您的尝试将注定失败。根据您的描述,情况并非如此; VS2005 和 VS2008 之间的运行时库不同,因此对象布局在编译器之间保持相同的可能性很小。您所指的“来自 Dinkumware 的东西”很可能是 Microsoft 使用 Dinkumware 的 C++ 标准库作为 ISTR。
在上面的示例中,您还遗漏了几条重要信息 - 您描述的类型(Server::StringArray 和 Server::KeyValueMap)是标准库容器。好的,但是什么 的标准库容器?这些容器是模板,除非您知道这些模板实例化的确切类型,否则您会有点卡住。
这个 DLL 是否打算从 C++ 中调用?它导出 JNI 接口(interface)的事实表明它可能不是第一个。除了 _Java_... 格式的符号之外,它是否导出任何其他公共(public)符号?
当然,如果没有其他方法,并且您必须使用 C++ 而不是 Java,您可能需要考虑将 JVM 嵌入到您的 C++ 应用程序中,并使用它来调用 C++ dll。这不是我所说的优雅解决方案,但它可能会奏效。
关于c++ - 如何从 C++ 调用 JNI DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1264214/