JNA Definition:
Jna:java Native Access, a JNI-based framework developed by Sun. JNI allows Java to invoke native C or C + + code.
differences between JNA and JNI (Java Native Interface):
Performance : JNA is inferior to JNI in performance. Since JNA is a layer on the basis of JNI.
Portability: JNA is better than JNI because developers don't need to write dynamic-link libraries as proxies.
Use : JNI uses the native keyword, maps native methods using a Java method, and uses System.loadlibrary;jna to represent dynamic-link libraries using a Java pretext. Using Native.loadlibrary
JNA installation using the environment:
native code: Write native code using C + + or C, or use existing native code. Specify the extern "C" __declspec (dllexport) before preparing the function or class to be used in Java. Then package the DLL into a dynamic-link library
java code : Download Jna.jar,https://github.com/java-native-access/jna. Then put the DLL file below the detailed project.
JNA using:
1. Prepare the DLL (this part is for people who have just started learning.) Can be browsed directly to the 2nd part)
We use Java to call DLLs from the generation of DLLs to the use of JNA, step by step commentary.
The DLL is generated first. In order to learn JNA. It's best if we build the DLL ourselves, I use the dev C + + (http://sourceforge.net/projects/orwelldevcpp/) tool to write C + + code. After installing dev C + +, we create a dllproject.
Then we create an. h file and a. cpp file. We need to define inside. H:
#if BUILDING_DLL#define DLLIMPORT extern "C" __declspec(dllexport)#else#define DLLIMPORT extern "C" __declspec(dllimport)#endif
Then we define two structs and two function functions in. h:
struct UserStruct{ longid; wchar_t* name; int age;};DLLIMPORTvoid sayUser(UserStruct* pUserStruct);struct CompanyStruct{ longid; wchar_t* name; UserStruct* users[100]; int count;};DLLIMPORTvoid sayCompany(CompanyStruct* pCompanyStruct);
Note here that the function declaration needs to be DLLIMPORT, where DLLIMPORT equals extern "C" __declspec (dllexport), No special treatment is required before a struct.
Implement Sayuser and Saycompany two functions in a. cpp file:
void sayUser(UserStruct* pUserStruct){ std::wcout<<L"hello:"<<pUserStruct->name<<std::endl;}
The function of the Sayuser function is to print out the name of the USERSTRUCT structure
void sayCompany(CompanyStruct* pCompanyStruct){ std::wcout<<L"hello:"<<pCompanyStruct->name<<std::endl; for(int i=0;i<pCompanyStruct->count;i++) { UserStruct* user=pCompanyStruct->users[i]; sayUser(user); }}
The function of the Saycompany function is to print out the name of the company structure and print the name of all USERSTRUCT members at the same time.
Then we implement it in the CPP file.
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved){ returnTRUE;}
Then build the DLL file, because the project name I defined is called jnatest, so the generated DLL file is called JNATest.dll.
2. Java calls DLL using JNA
We need to create a interface, here we name TESTDLL1, and then extends Library. We need to map the userstruct and COMPANYSTRUCT two structures to Java, such as the following code:
Public class userstruct extends Structure { Public Static class byreference extends userstruct implements Structure . byreference {}; Public Static class byvalue extends userstruct implements Structure. Byvalue {} PublicNativelong ID; PublicWString name; Public intAge;}
Byreference refers to the pointer, byvalue refers to the value, then the following three fields corresponding. h file in the Userstruct three fields, the order must not be wrong. As memory is passed to the C function call, reading is read in the order of the struct in C, so the order must not be wrong.
Similarly companystruct mappings in Java are as follows:
Public class companystruct extends Structure{ Public Static class byreference extends companystruct implements Structure . byreference {}; Public Static class byvalue extends companystruct implements Structure. Byvalue {}; PublicNativelong ID; PublicWString name;//need to use ToArray. Because the memory space in Java is not contiguous. So use the ToArray method provided by JNA to generate contiguous memory space PublicUserstruct.byreference[] users= (userstruct.byreference[])NewUserstruct.byreference (). ToArray ( -); Public intCount;}
There's a place that needs special attention. Otherwise, a null error occurs. is public userstruct.byreference[] users= (userstruct.byreference[]) new Userstruct.byreference (). ToArray (+); This sentence, assuming that the public userstruct.byreference[] users=new userstruct.byreference[100], then the call will be an error. The reason is that Java's memory space is usually discontinuous, and we need contiguous memory space, where we need to generate an array using the ToArray function provided by JNA.
The following piece of code is very important to load the DLL:
TestDll1 INSTANCE=(TestDll1) Native.loadLibrary("JNATest",TestDll1.class);
Then declare the native function we want to call in Java:
publicvoidsayUser(UserStruct userStruct);publicvoidsayCompany(CompanyStruct companyStruct);
Then we create a test.java, and in the main function we test whether we can invoke the native function.
First Test Sayuser:
UserStruct.ByReference userStruct=new UserStruct.ByReference();userStruct.id=new NativeLong(100);userStruct.age=30;userStruct.name=new WString("SBY");TestDll1.INSTANCE.sayUser(userStruct);
And then execute. Will print out the Hello:sby
Again test Saycompany:
Companystruct. ByreferenceCompanystruct=new companystruct. Byreference();Companystruct. ID=new Nativelong (2);Companystruct. Name=new WString ("hehe");Companystruct. Count=Ten;Userstruct. ByreferencePuserstruct=new userstruct. Byreference();Puserstruct. ID=new Nativelong ( -);Puserstruct. Age= About;Puserstruct. Name=new WString ("SBY");Puserstruct. Write();for (int i=0; i<companystruct.count;i++) {Companystruct. The Users[I]=puserstruct;}testdll1. INSTANCE. Saycompany(companystruct);
Will output a hello:hehe and 10 Hello:sby
Some places will say that the need to puserstruct.write () This line of code, the purpose is to hold the memory, not to be released by the GC, but when I test the time without adding this line can also be executed accurately. This JNA is expected to provide the ToArray function.
The above is my JNA learning experience. The reason for inserting such an article in machine learning's blog is that most of the machine Leanring's code is written in C or C + +. Some scenarios will require writing Java programs. At this point we need to use Java to invoke the C or C + + functions that have been written.
The above source Portal: Http://yun.baidu.com/share/link?
shareid=2278504517&uk=3977203577
Using JNA, let Java invoke native code