我正在尝试包装一些用于Java的旧代码,很高兴看到Swig能够处理头文件,并且生成了一个几乎可以正常工作的出色包装器。现在,我正在寻找使它真正起作用的深层魔术。
CI中的功能看起来像这样
DLL_IMPORT int DustyVoodoo(char *buff, int len, char *curse);
此函数返回的该整数是万一失败的错误代码。参数是
buff
是一个字符缓冲区 len
是缓冲区中数据的长度curse
另一个字符缓冲区,其中包含调用DustyVoodoo的结果因此,您可以看到行进方向,结果实际上是通过第三个参数返回的。这也len
很令人困惑,因为这可能是两个缓冲区的长度,在调用代码中它们总是被分配为相同的大小,但是鉴于DustyVoodoo
我不认为它们需要相同。为了安全起见,实际上两个缓冲区的大小应相同,例如512个字符。
为绑定生成的C代码如下:
SWIGEXPORT jint JNICALL Java_pemapiJNI_DustyVoodoo(JNIEnv *jenv, jclass jcls, jstring
jarg1, jint jarg2, jstring jarg3) {
jint jresult = 0 ;
char *arg1 = (char *) 0 ;
int arg2 ;
char *arg3 = (char *) 0 ;
int result;
(void)jenv;
(void)jcls;
arg1 = 0;
if (jarg1) {
arg1 = (char *)(*jenv)->GetStringUTFChars(jenv, jarg1, 0);
if (!arg1) return 0;
}
arg2 = (int)jarg2;
arg3 = 0;
if (jarg3) {
arg3 = (char *)(*jenv)->GetStringUTFChars(jenv, jarg3, 0);
if (!arg3) return 0;
}
result = (int)PemnEncrypt(arg1,arg2,arg3);
jresult = (jint)result;
if (arg1) (*jenv)->ReleaseStringUTFChars(jenv, jarg1, (const char *)arg1);
if (arg3) (*jenv)->ReleaseStringUTFChars(jenv, jarg3, (const char *)arg3);
return jresult;
}
它所做的是正确的。但是,它错过了一个事实,即cursed
它不仅是输入,而且会被函数更改并应作为输出返回。它还不知道Java字符串确实是缓冲区,应该由适当大小的数组作为后盾。
我认为Swig在这里可以做正确的事情,只是无法从文档中弄清楚如何告诉Swig它需要知道什么。房子里有字型图吗?
感谢托马斯的正确指导。解决方案是创建一个使用StringBuffer的自定义类型映射,以将结果返回。我examples/java/typemap
在SWIG安装目录中找到了代码。在搜索之前,我一定忽略了这一点。
我已在下面附加了示例代码,目前正在使用建议的替代方法。但是,使用BYTE类型映射的第一种方法可能需要对Java代码进行一些更改,但从长远来看实际上可能更有意义。
感谢您的帮助,现在我可以看看我是否可以接受自己的答案…
/* File : example.i */
%module example
%{
/*
example of a function that returns a value in the char * argument
normally used like:
char buf[bigenough];
f1(buf);
*/
void f1(char *s) {
if(s != NULL) {
sprintf(s, "hello world");
}
}
void f2(char *s) {
f1(s);
}
void f3(char *s) {
f1(s);
}
%}
/* default behaviour is that of input arg, Java cannot return a value in a
* string argument, so any changes made by f1(char*) will not be seen in the Java
* string passed to the f1 function.
*/
void f1(char *s);
%include various.i
/* use the BYTE argout typemap to get around this. Changes in the string by
* f2 can be seen in Java. */
void f2(char *BYTE);
/* Alternative approach uses a StringBuffer typemap for argout */
/* Define the types to use in the generated JNI C code and Java code */
%typemap(jni) char *SBUF "jobject"
%typemap(jtype) char *SBUF "StringBuffer"
%typemap(jstype) char *SBUF "StringBuffer"
/* How to convert Java(JNI) type to requested C type */
%typemap(in) char *SBUF {
$1 = NULL;
if($input != NULL) {
/* Get the String from the StringBuffer */
jmethodID setLengthID;
jclass sbufClass = (*jenv)->GetObjectClass(jenv, $input);
jmethodID toStringID = (*jenv)->GetMethodID(jenv, sbufClass, "toString", "()Ljava/lang/String;");
jstring js = (jstring) (*jenv)->CallObjectMethod(jenv, $input, toStringID);
/* Convert the String to a C string */
const char *pCharStr = (*jenv)->GetStringUTFChars(jenv, js, 0);
/* Take a copy of the C string as the typemap is for a non const C string */
jmethodID capacityID = (*jenv)->GetMethodID(jenv, sbufClass, "capacity", "()I");
jint capacity = (*jenv)->CallIntMethod(jenv, $input, capacityID);
$1 = (char *) malloc(capacity+1);
strcpy($1, pCharStr);
/* Release the UTF string we obtained with GetStringUTFChars */
(*jenv)->ReleaseStringUTFChars(jenv, js, pCharStr);
/* Zero the original StringBuffer, so we can replace it with the result */
setLengthID = (*jenv)->GetMethodID(jenv, sbufClass, "setLength", "(I)V");
(*jenv)->CallVoidMethod(jenv, $input, setLengthID, (jint) 0);
}
}
/* How to convert the C type to the Java(JNI) type */
%typemap(argout) char *SBUF {
if($1 != NULL) {
/* Append the result to the empty StringBuffer */
jstring newString = (*jenv)->NewStringUTF(jenv, $1);
jclass sbufClass = (*jenv)->GetObjectClass(jenv, $input);
jmethodID appendStringID = (*jenv)->GetMethodID(jenv, sbufClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
(*jenv)->CallObjectMethod(jenv, $input, appendStringID, newString);
/* Clean up the string object, no longer needed */
free($1);
$1 = NULL;
}
}
/* Prevent the default freearg typemap from being used */
%typemap(freearg) char *SBUF ""
/* Convert the jstype to jtype typemap type */
%typemap(javain) char *SBUF "$javainput"
/* apply the new typemap to our function */
void f3(char *SBUF);
与另一个包围盒求并集,得到的也是一个包围盒。 参数 名称 类型 默认值 描述 other zrender.BoundingRect 另一个包围盒。 返回值 新的包围盒,类型:zrender.BoundingRect。
判断两个包围盒是否相交。 参数 名称 类型 默认值 描述 other zrender.BoundingRect 另一个包围盒。 返回值 相交部分的包围盒,类型:zrender.BoundingRect。
从另一个包围盒复制属性。 参数 名称 类型 默认值 描述 other zrender.BoundingRect 另一个包围盒。
To learn more about the Basic Elements To see the full API document in Markdown format, see APIs To contribute to Gio.js's code base, read Developer Guide
HTTP 303 See Other重定向状态响应代码(通常作为一个 PUT或POST操作的结果发回)表示重定向不链接到新上载的资源,而是链接到其他页面,如确认页面或上载进度页面。用于显示此重定向页面的方法始终是GET。 状态 303 See Other 规范 规范 标题 RFC 7231,第6.4.4节:303见其他 超文本传输协议(HTTP / 1.1):语义和内容 浏览器兼容性 Featur
链接静态库优化 Other Linker Flags (OTHER_LDFLAGS)作用效果及作用时机探究 一、准备 文件目录结构 . ├── OCStaticLib │ ├── OCTest.h │ ├── OCTest.m │ ├── OCTest.o │ ├── build.sh │ ├── libOCTest │ └── libOCT