英文:
Mapping primitive type in JNA while keeping the native typedef class
问题
我在我的DLL中有这个类型定义:
typedef int FMOD_MEMORY_TYPE;
我能否在Java中为此创建一个类,以便我知道FMOD_MEMORY_TYPE
只是一个int
?
public final class FMOD_MEMORY_TYPE {
public int value;
}
我假设它占用相同的内存?
这个类型经常传递给函数,如果在Java中它有自己的类似于typedef的定义,将会更容易。如果不行,我该如何在Java中进行类型映射?
基本上它只是一个int
,但是如果必须将所有出现的情况都替换为int
,会花费很多时间,使用类似typedef的方法会更容易。
基本上,我希望能够像这样映射代码:
(C):
void some_function(FMOD_MEMORY_TYPE argument);
<=> Java:
public void some_function(FMOD_MEMORY_TYPE arg);
而不是:
public void some_function(int arg);
英文:
I have this type defined in my DLL:
typedef int FMOD_MEMORY_TYPE;
Can I make a class for this in Java so I will know FMOD_MEMORY_TYPE
is just an int
?
public final class FMOD_MEMORY_TYPE {
public int value;
}
As I presume it takes the same amount of memory?
This type is passed into functions a lot and it would make it a lot easier if in Java it had its own typedef almost too. If not, how can I make some of mapping to a type in Java?
Essentially it's just an int
but having to replace all occurrences with int
would take a lot of time and this would be easier.
Essentially I Want to be able to map the code like this:
(C):
void some_function(FMOD_MEMORY_TYPE argument);
<=> Java:
public void some_function(FMOD_MEMORY_TYPE arg);
instead of:
public void some_function(int arg);
答案1
得分: 0
是的,您可以为基本数据类型创建一个包装类,但并不像您描述的那么简单。
包装类为您提供了一些方便,以便像您请求的那样移植代码,同时还提供了类型安全性。这个类在Java端会占用一些额外的内存,因为您需要为整个对象分配空间,而不仅仅是基本数据类型的内存。并且在存储和检索内部值时会有一点点性能损耗。然而,如果这些权衡对您来说是值得的,并且不用在性能敏感的应用程序中使用,那就没有问题。
但是,您不能像您在问题中描述的那样仅仅使用一个类,而是需要为JNA添加附加功能,以确定对象的字节大小及其相应的本机类型。具体来说,您需要实现NativeMapped
接口。最简单的方法是通过扩展已经为您完成这些工作的现有JNA类来实现。
对于整数类型定义,我建议您创建一个扩展IntegerType
的类型,并为您提供访问那些方法的方式。所以在您的情况下,我会这样做:
public final class FMOD_MEMORY_TYPE extends IntegerType {
public static final int SIZE = 4; // 字节
public FMOD_MEMORY_TYPE() {
this(0);
}
public FMOD_MEMORY_TYPE(int value) {
super(SIZE, value);
}
}
通过这样做,您将继承IntegerType
的setValue()
方法,并继承所有核心Java Number 类方法,比如 intValue()
。
您还可以选择实现Comparable
接口或根据需要添加其他方法。
在JNA的WinDef类等地方有很多示例。
英文:
Yes, you can create a wrapper class for primitives, but not quite as simply as you describe.
A wrapper class gives you some ease in porting code as you've requested, as well as type safety. The class will take a little bit more memory on the Java side as you're allocating space for an entire object instead of simply the memory for a primitive. And there will be a tiny performance hit for storing and retrieving the internal value. However, if these trade-offs are worth it to you and aren't used in a performance-sensitive application, it's not a problem.
However, you can't just use a class as you've described in your question without adding additional functionality for JNA to determine the byte size of the object and its corresponding native equivalent. Specifically, you would have to implement the NativeMapped
interface. This is most easily done by extending an existing JNA class which already does this work for you.
For an integer typedef, I would recommend that you create a type that extends IntegerType
and provides you access to those methods. So in your case, I'd do:
public final class FMOD_MEMORY_TYPE extends IntegerType {
public static final int SIZE = 4; // bytes
public FMOD_MEMORY_TYPE() {
this(0);
}
public FMOD_MEMORY_TYPE(int value) {
super(SIZE, value);
}
}
Doing this will will inherit setValue()
from IntegerType
and inherit all of the core Java Number class methods like intValue()
.
You could also choose to implement Comparable
or add other methods as needed.
There are plenty of examples in JNA's WinDef class, among others.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论