- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 SWIG 为 Spotify library 生成了一个包装器在 java 。头文件包含
typedef struct sp_session_config {
...
const void *application_key; ///< Your application key
...
这应该允许我在 Java 中设置应用程序 key :
sp_session_config cfg = new sp_session_config();
cfg.setApplication_key(appkey);
C中的key是这样声明的
const uint8_t g_appkey[] = {0x01, 0xB4, 0xF9, 0x33, .... }
问题是我不知道如何在 Java 中创建 key 。 appkey 的类型必须是 SWIGTYPE_p_void
。
我试图在 .i 文件中添加:
%include "carrays.i"
%array_functions(uint8_t, uint8Array);
能够使用这些函数在 Java 中创建 C 数组:
new_uint8Array
uint8Array_setitem
没有成功。
我该如何解决我的问题?欢迎提供一个简单的小例子。
最佳答案
你在 carrays.i 的正确路线上,虽然通常我更愿意使用 %array_class
而不是 %array_functions
如果有选择的话。问题是你的 array_functions/array_class 给你一个 SWIGTYPE_p_unsigned_char
(即指向 unsigned char
的指针的代理),而你需要一个 void
指针并且有由于 Java 中的强类型,没有简单的方法可以在两者之间进行转换。不过,我们可以解决这个问题。
为了说明这个答案,我创建了一个非常简单的头文件来重现您的问题:
typedef struct sp_session_config {
const void *application_key; ///< Your application key
} session_config;
所以问题是我们无法使用 array_class/array_function 生成的 uint8_t
数组调用 setApplication_key()
,因为类型不匹配。
对此有很多可能的解决方案。一种方法可能是告诉 SWIG 忽略 sp_session_config
中的 application_key
,而是假装它是一个 uint8_t* application_key
。为此,您需要在 C 中为完成工作的包装器提供一个 set/get 函数(在这种情况下微不足道)并使用 %ignore
隐藏“真实”成员,% extend
添加“假”成员和 %rename
停止 %ignore
忽略假成员:
%module test
%{
#include "test.h"
#include <stdint.h>
// Internal helpers for our fake memeber
static void session_config_application_key_set(session_config *cfg, const uint8_t *arr) {
cfg->application_key = arr;
}
static const uint8_t *session_config_application_key_get(const session_config *cfg) {
return cfg->application_key;
}
%}
%include <carrays.i>
%include <stdint.i>
%array_class(uint8_t, uint8Array);
%ignore sp_session_config::application_key; // ignore the real one when we see it
%include "test.h"
%rename("%s") sp_session_config::application_key; // unignore for extend
%extend session_config {
uint8_t *application_key;
}
这足以让我们用 Java 编写:
public class run {
public static void main(String[] argv) {
session_config cfg = new session_config();
uint8Array key = new uint8Array(4);
key.setitem(0, (short)100); key.setitem(1, (short)101);
key.setitem(2, (short)102); key.setitem(3, (short)103);
cfg.setApplication_key(key.cast());
}
}
或者,如果您愿意,可以使用类型映射系统将成员公开为 uint8_t*
:
%module test
%{
#include "test.h"
%}
%include <carrays.i>
%include <stdint.i>
%array_class(uint8_t, uint8Array);
%typemap(jstype) const void *application_key "$typemap(jstype, const uint8_t*)"
%typemap(javain) const void *application_key "$typemap(jstype, const uint8_t*).getCPtr($javainput)"
%typemap(javaout) const void *application_key {
long cPtr = $jnicall;
return (cPtr == 0) ? null : new $typemap(jstype, const uint8_t*)(cPtr, $owner);
}
%include "test.h"
仅匹配 const void *application_key
并在接口(interface)中生成代码以使用包装的 uint8_t*
而不是 void*
。
另一种可能的方法是通过提供 struct
的特殊定义,简单地向 SWIG 声明成员是 uint8_t*
在接口(interface)文件中:
%module test
%{
#include "test.h"
%}
%include <carrays.i>
%include <stdint.i>
%array_class(uint8_t, uint8Array);
typedef struct sp_session_config {
const uint8_t *application_key;
} session_config;
// Ignore the one in the header file, use our special version instead
%ignore sp_session_config;
%include "test.h"
这样做很简单,但维护起来比较棘手 - 每次 sp_session_config
更改时,您都必须确保更新接口(interface)文件以匹配它,否则您将面临不公开甚至不正确的风险公开结构
。
请注意:注意这些示例中的所有权 - Java 端的数组保留所有权,因此您需要确保:
free()
)如果你愿意,你可以让 C 库获得内存的所有权,这些例子中最容易做到这一点的是使用类型映射的例子。 (您可以修改 javain 类型映射以也获得所有权)。
最后,对于另一种可能的解决方案,您可以使用 a little bit of JNI或 yet more other techniques正如我过去回答的那样,使用 Java 数组或为此生成合适的代码。
关于java - 在生成的接口(interface)中公开空指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11535615/
我正在尝试在我的代码库中为我正在编写的游戏服务器更多地使用接口(interface),并了解高级概念以及何时应该使用接口(interface)(我认为)。在我的例子中,我使用它们将我的包相互分离,并使
我有一个名为 Widget 的接口(interface),它在我的整个项目中都在使用。但是,它也用作名为 Widget 的组件的 Prop 。 处理此问题的最佳方法是什么?我应该更改我的 Widget
有一个接口(interface)可以是多个接口(interface)之一 interface a {x:string} interface b {y:string} interface c {z:st
我遇到了一种情况,我需要调用第三方服务来获取一些信息。这些服务对于不同的客户可能会有所不同。我的界面中有一个身份验证功能,如下所示。 interface IServiceProvider { bool
在我的例子中,“RequestHandlerProxy”是一个结构,其字段为接口(interface)“IAdapter”,接口(interface)有可能被调用的方法,该方法的输入为结构“Reque
我有一个接口(interface)Interface1,它已由类A实现,并且设置了一些私有(private)变量值,并且我将类A的对象发送到下一个接受输入作为Interface2的类。那么我怎样才能将
假设我有这样的类和接口(interface)结构: interface IService {} interface IEmailService : IService { Task SendAs
有人知道我在哪里可以找到 XML-RPC 接口(interface)的定义(在 OpenERP 7 中)?我想知道创建或获取对象需要哪些参数和对象属性。每个元素的 XML 示例也将非常有帮助。 最佳答
最近,我一直在阅读有关接口(interface)是抽象的错误概念的文章。一篇这样的帖子是http://blog.ploeh.dk/2010/12/02/InterfacesAreNotAbstract
如果我有一个由第三方实现的现有 IInterface 后代,并且我想添加辅助例程,Delphi 是否提供了任何简单的方法来实现此目的,而无需手动重定向每个接口(interface)方法?也就是说,给定
我正在尝试将 Article 数组分配给我的 Mongoose 文档,但 Typescript 似乎不喜欢这样,我不知道为什么它显示此警告/错误,表明它不可分配. 我的 Mongoose 模式和接口(
我有两个接口(interface): public interface IController { void doSomething(IEntity thing); } public inte
是否可以创建一个扩展 Serializable 接口(interface)的接口(interface)? 如果是,那么扩展接口(interface)的行为是否会像 Serilizable 接口(int
我试图在两个存储之间创建一个中间层,它从存储 A 中获取数据,将其转换为相应类型的存储 B,然后存储它。由于我需要转换大约 50-100 种类型,我希望使用 map[string]func 并根据 s
我正在处理一个要求,其中我收到一个 JSON 对象,其中包含一个日期值作为字符串。我的任务是将 Date 对象存储在数据库中。 这种东西: {"start_date": "2019-05-29", "
我们的方法的目标是为我们现有的 DAO 和模型类引入接口(interface)。模型类由各种类型的资源 ID 标识,资源 ID 不仅仅是随机数,还带有语义和行为。因此,我们必须用对象而不是原始类型来表
Collection 接口(interface)有多个方法。 List 接口(interface)扩展了 Collection 接口(interface)。它声明与 Collection 接口(int
我有一个 Java 服务器应用程序,它使用 Jackson 使用反射 API 对 DTO 进行一般序列化。例如对于这个 DTO 接口(interface): package com.acme.libr
如果我在 Kotlin 中有一个接口(interface): interface KotlinInterface { val id: String } 我可以这样实现: class MyCla
我知道Java中所有访问修饰符之间的区别。然而,有人问了我一个非常有趣的问题,我很难找到答案:Java 中的 private 接口(interface)和 public 接口(interface)有什
我是一名优秀的程序员,十分优秀!