当前位置:网站首页>JNA learning notes 1: Concepts

JNA learning notes 1: Concepts

2022-07-07 13:08:00 Mountain Ghost ballad me

By default , all Structure Object before native function call , All of them Java Fields are copied into their native memory , And copy back after calling .

Default type mapping

Java The original type ( And its object equivalents ) Directly map to a native of the same size C type .

NativeTypeSizeJava TypeCommon Windows Types
char8-bit integerbyteBYTE, TCHAR
short16-bit integershortWORD
wchar_t16/32-bit charactercharTCHAR
int32-bit integerintDWORD
intboolean valuebooleanBOOL
long32/64-bit integerNativeLongLONG
longlong 64-bit integerlong__int64
float32-bit FPfloat
double64-bit FPdouble
char*C stringStringLPCSTR
void*pointerPointerLPVOID, HANDLE, LPXXX

Unsigned types use the same mapping as signed types . C Enumerations can usually be associated with “int” swap .

Use pointers and arrays

Raw array parameters ( Including structure ) They correspond to Java Type said . for example :

//  original  C  Statement 
void fill_buffer(int *buf, int len);
//Java Writing 
void fill_buffer(int buf[], int len); // same thing with array syntax
//  equivalent  JNA  mapping 
void fill_buffer(int[] buf, int len);

Be careful : If parameters are to be used for native functions outside the scope of function call , Must be used Memory or NIO Direct buffer . Java The memory provided by the original array is only valid for use by native code during function calls .

C Array of strings ( for example char* argv[] To C main), stay Java You can use... In the code String[] Express . JNA Will be automatically passed with NULL An equivalent array of final elements .

Use Structures and Unions

When a function needs to point to struct The pointer of , You should use Java Of Structure, If struct Passed by value, it will return , You only need to modify the parameter or return type class declaration slightly .

Usually , We need to define Structure Public static class derived from . namely :static class AttachOptions extends Structure Like this .
This allows the structure to share any options defined for the library interface ( Such as custom type mapping ). You must be in FieldOrder Notes or getFieldOrder() The list returned by the method contains the field names of each declaration in order .

If the function requires an array of structures ( Continuously allocate... In memory ), You can use Java Structure[]. Pass in a Structure Array time , There is no need to initialize array elements ( The function call will assign you 、 Zero memory , And assign elements to you ). If you really need to initialize the array , You should use Structure.toArray Method to obtain continuous Structure Array of elements , It can then be initialized as needed .

Unions It is usually interchangeable with the structure , But you are required to use setType Method indicates which Unions Field is active , Then it can be correctly passed to the function call .

https://github.com/java-native-access/jna/blob/master/www/StructuresAndUnions.md

Use ByReference Parameters

When a function accepts a pointer to a type parameter , You can use one of these ByReference Type to capture the return value , Or subclass your own values . for example :

//  original  C  Statement 
void allocate_buffer(char **bufp, int* lenp);

//  equivalent  JNA  mapping 
void allocate_buffer(PointerByReference bufp, IntByReference lenp);

//  usage 
PointerByReference pref = new PointerByReference();
IntByReference iref = new IntByReference();
lib.allocate_buffer(pref, iref);
Pointer p = pref.getValue();
byte[] buffer = p.getByteArray(0, iref.getValue());

perhaps , You can use Java Array , but ByReference Better communicate the intent of the code . except getByteArray() outside ,Pointer Class also provides many accessor methods , They are effectively used as type conversions in memory .

Type safe pointers can be derived from PointerType Class to declare .

https://github.com/java-native-access/jna/blob/master/www/ByRefArguments.md#using-byreference-arguments

In reference to :JNI Convenient development framework JNA The structural parameter body transfer of the frame ( Four ) After this article , Practice has come to the conclusion ByReference Passing can modify the value of member variables in the structure ,ByValue Transmission cannot .

from Java To Native Custom mapping for

TypeMapper Classes and related interface providers will be used as parameters 、 Returns any of the values or structure members Java Type conversion to or from native type . Example Win32 API The interface uses a type mapper to Java Boolean values are converted to Win32 BOOL type . TypeMapper The instance is passed to Native.load In the option mapping of TYPE_MAPPER The value of the key is passed .

perhaps , User defined types can implement NativeMapped Interface , This interface determines the conversion between native types on a class by class basis .

You can also customize Java Mapping of method names to corresponding native function names . StdCallFunctionMapper It is a kind of from Java Interface method signature is automatically generated std​​call Implementation of decorated function name . The mapper should be passed to Native.load In the option mapping of the call OPTION_FUNCTION_MAPPER The value of the key is passed .

https://github.com/java-native-access/jna/blob/master/www/CustomMappings.md

involve C Knowledge of language

One 、 The essential difference between ordinary variables and

When it comes to the difference between ordinary variables and pointer variables , I prefer to look at both from a higher perspective . First of all , Both are variables , Since it's a variable , It will include address and value , for example int a , use &a Get the address of the variable , use a Get the value of the variable ; The difference between ordinary variables and pointer variables is , The values of these two variables have different meanings , Generally speaking , The value of a normal variable , Just a value for programmers , The value of the pointer variable is different , Its value stores the addresses of other variables . Since ordinary variables and pointer variables are different , Then declaring a pointer variable must be different from ordinary variables ,c Language use int* b Declare variables b Is a pointer variable , Namely variable b The value of can be resolved to the address of another variable .

int a=3;
int* b=&a;

Variable a Value a yes 3, Address &a The assumption is 00E1FEA0;

Variable b Value b It's a variable a The address of 00E1FEA0,&b Express b The address of , Generally speaking, I don't care much ,b Indicates that the address obtained is b( Be clear , This is a variable a The address of ) The value corresponding to the variable of , in other words b=3;

take C Command to package language files into shared library files

#  Notice the last two parameters  libhello.so( Own designated name ) hello.c(c file )
gcc -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o libhello.so hello.c

summary

In reference to :JNI Convenient development framework JNA Introduction to framework ( One ) After the series , I learned that JNA How does it work .

  1. Java Interface signature and C file (xxx.c file ) Chinese method signature should always . Conversion between types , We need to pay attention to . General types and Java It can simply correspond to , String type C In language is char* str, however int *c In this case ,Java You need to use Pointer Corresponding .
  2. Pointer Although it can meet C Pointer types in languages , But its memory management is also similar to C The language is the same , We need to maintain it manually , So there it is ByReference class And derived classes IntByReference(int)、PointerByReference( character string ) Wait for Java Automatic memory management class .Pointer class And Reference class In general, the latter is better , But for more layers of pointer references , Probably Pointer More appropriate .
原网站

版权声明
本文为[Mountain Ghost ballad me]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207071059488515.html