JNA调用dll(c++)附带解析xml——JNA-JNI(四)
系列文章:
Java通过JNI调用C++动态链接库dll,并打在jar包内 ——JNA-JNI(一)
Java使用JNA调用C++动态链接库——JNA-JNI(二)
Mac M1 Xcode创建动态链接库dylib(c++)——JNA-JNI(三)
JNA调用dll(c++)附带解析xml——JNA-JNI(四)
JNA参数类型转换(含接收、发送结构体)——JNA-JNI(五)
使用tinyxml2
使用tinyxml2:https://github.com/leethomason/tinyxml2,下载zip解压即可
将 tinyxml2.cpp
和 tinyxml2.h
拷贝至项目目录,使用时包含头文件和引入名字空间
#include "tinyxml2.h"
using namespace tinyxml2
c++解析xml源码
xxx.cpp文件,生成dll
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include "xxx.h"
#include "tinyxml2.h"
using namespace std;
using namespace tinyxml2;
//function:create a xml file
//param:xmlPath:xml文件路径
//return:0,成功;非0,失败
int createXML(const char* xmlPath)
{
const char* declaration = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>";
tinyxml2::XMLDocument doc;
doc.Parse(declaration);//会覆盖xml所有内容
//添加申明可以使用如下两行
//XMLDeclaration* declaration=doc.NewDeclaration();
//doc.InsertFirstChild(declaration);
XMLElement* root = doc.NewElement("DBUSER");
doc.InsertEndChild(root);
return doc.SaveFile(xmlPath);
}
//获取xml文件所有内容
void getXMLContent(const char* xmlPath, string& content)
{
tinyxml2::XMLDocument doc;
if (doc.LoadFile(xmlPath) != XML_SUCCESS)
{
cout << "load xml file failed" << endl;
return;
}
XMLPrinter printer;
doc.Print(&printer);
content = printer.CStr();
}
//查询xml文件的指定节点
XMLElement* queryUserNodeByName(XMLElement* root, const string& userName)
{
XMLElement* userNode = root->FirstChildElement("User");
while (userNode != NULL)
{
if (userNode->Attribute("Name") == userName)
{
break;
}
userNode = userNode->NextSiblingElement();//下一个兄弟节点
}
return userNode;
}
void xmltest() {
//获取xml文件的所有信息
string content;
getXMLContent("C:/Users/haonan/source/repos/example.xml", content);
cout << content << endl;
//获取文件内容之后,解析字符串
tinyxml2::XMLDocument doc;
doc.Parse(content.c_str());
XMLElement* rootElement = doc.RootElement();
// const char* rootName = rootElement->Value();
XMLElement* userNode;
userNode = queryUserNodeByName(rootElement, "lvlv");
struct Student s1;//定义结构体类型变量s1
if (userNode != NULL)
{
string gender = userNode->FirstChildElement("Gender")->GetText();
string mobile = userNode->FirstChildElement("Mobile")->GetText();
string email = userNode->FirstChildElement("Email")->GetText();
s1.Gender = atoi(gender.c_str());//结构体变量的引用
s1.Mobile = (char*)mobile.c_str();
s1.Email = atoi(email.c_str());
s1.column = &email;
cout << s1.Gender << endl;
cout << s1.Mobile << endl;
cout << s1.Email << endl;
cout << s1.column << endl;
}
}
xxx.h文件
#ifndef SIMPLE_H_INCLUDED
#define SIMPLE_H_INCLUDED
#include <string>
#include <windows.h>
using namespace std;
/*声明结构体*/
typedef struct Student
{
int Gender;
char *Mobile;
int Email;
void *column;
};
#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif // __cplusplus
EXPORT void xmltest();
#endif // SIMPLE_H_INCLUDED
可能的报错: IntelliSense: “XMLDocument” 不明确
原因: 由于所引用的某些头文件中也使用了 XMLDocument 这个名称,造成命名冲突。如 “windows.h” 也包含了XMLDocument
解决办法:指明命名空间,使用tinyxml2::XMLDocument
JNA调用
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class);
DemoApplication.CLibrary.INSTANCE.xmltest();
}
public interface CLibrary extends Library {
// 通过INSTANCE这个常量,就可以获得这个接口的实例
DemoApplication.CLibrary INSTANCE = (DemoApplication.CLibrary) Native.loadLibrary("Projectxx", DemoApplication.CLibrary.class);
public void xmltest();
}
运行结果
使用的example.xml如下
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DBUSER>
<User Name="lvlv" Password ="123456">
<Gender>1</Gender>
<Mobile>111</Mobile>
<Email>222</Email>
</User>
</DBUSER>
java运行截图
参考链接
https://blog.csdn.net/qq_24127015/article/details/88792741
https://blog.csdn.net/K346K346/article/details/48750417