SWIG経由でJavaを使用して呼び出したいC関数がありますが、どのようにsockaddr_in C構造体を処理するのかは分かりません。誰でも私がsockaddr_inをどのように扱うことができるかについての例がありますか?SWIGを使用してSockaddr_in C構造体をJavaにマップする方法
答えて
それは今少し古い見えますが、swig.orgにsockaddr_in
を包む上の記事は、実際にあります。
基本的には、あなたのために新しいsockaddr_in
を作成する関数を作成し、Javaで簡単に渡すことができるものとして記入する必要がある値の引数を取っていました。
%module sock // Name of our module
%{
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
/* Set some values in the sockaddr_in structure */
struct sockaddr *new_sockaddr_in(short family, unsigned long hostid, int port) {
struct sockaddr_in *addr;
addr = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
bzero((char *) addr, sizeof(struct sockaddr_in));
addr->sin_family = family;
addr->sin_addr.s_addr = hostid;
addr->sin_port = htons(port);
return (struct sockaddr *) addr;
}
%}
// Add these constants
enum {AF_UNIX, AF_INET, SOCK_STREAM, SOCK_DGRAM, SOCK_RAW,
IPPROTO_UDP, IPPROTO_TCP, INADDR_ANY};
#define SIZEOF_SOCKADDR sizeof(struct sockaddr)
// Wrap these functions
struct sockaddr *new_sockaddr_in(short family, unsigned long, int port);
しかしSWIGでこれをラップのよりよい方法はあり、私たちは「はるかに感じるであろう、代わりにjava.net.InetSocketAddress
を使用するタイプマップを書くことができます。これは、リンク先の記事のバージョンをトリミングし、少し更新ですインタフェースのJava側の「ナチュラル:
%typemap(jni) sockaddr_in *ADDR "jobject"
%typemap(jtype) sockaddr_in *ADDR "java.net.InetSocketAddress"
%typemap(jstype) sockaddr_in *ADDR "java.net.InetSocketAddress"
%typemap(in) (sockaddr_in *ADDR) {
$1 = new sockaddr_in;
$1->sin_family = AF_INET;
jclass inetsockaddr = jenv->FindClass("java/net/InetSocketAddress");
assert(inetsockaddr);
// TODO: check return
jmethodID pmid,addrmid,ipbytemid;
pmid = jenv->GetMethodID(inetsockaddr, "getPort", "()I");
assert(pmid);
jint port = jenv->CallIntMethod($input, pmid);
$1->sin_port = htons(port);
jclass inetaddr = jenv->FindClass("java/net/InetAddress");
assert(inetaddr);
addrmid = jenv->GetMethodID(inetsockaddr, "getAddress", "()Ljava/net/InetAddress;");
assert(addrmid);
jobject addrobj = jenv->CallObjectMethod($input, addrmid);
assert(addrobj);
ipbytemid = jenv->GetMethodID(inetaddr, "getAddress", "()[B");
assert(ipbytemid);
jbyteArray barr = static_cast<jbyteArray>(jenv->CallObjectMethod(addrobj, ipbytemid));
assert(barr);
jbyte *bytes = jenv->GetByteArrayElements(barr, 0);
assert(bytes);
memcpy(&$1->sin_addr.s_addr, bytes, 4);
$1->sin_addr.s_addr = htonl($1->sin_addr.s_addr);
jenv->ReleaseByteArrayElements(barr, bytes, JNI_ABORT); // No changes copied back
}
%typemap(freearg) (sockaddr_in *ADDR) {
delete $1;
}
%typemap(javain) sockaddr_in *ADDR "$javainput"
基本的にこれはjava.net.InetSocketAddress
のgetAddress()
とgetPort()
メソッドを呼び出し、呼び出しのためstruct sockaddr_in
を作成するために、結果を使用しています。
注:
- 私たちはあまりにも適切にAF_INET6をサポートするべきである私は
- 右ここでバイト順序を持って100%わからない - 私たちは見て与えられた
InetSocketAddress
を検査する必要があるだろうそのサブクラスは型マップ自体にあります。 - タイプマップはありません。
out
これは基本的に逆の手順ですが、JNIコードは新しいJavaオブジェクトを作成します。 - アサーションはかなり醜いです。
は完全にするためにも、何のJNIを含まないどの本を、ラップが、Javaの少しを書くの第3の可能な方法があります。最初の例のようにSWIGでstruct sockaddr
をラップした後、sockaddr
を使用してラップされた関数を返すと、java.net.InetSocketAddress
オブジェクトが返され、2つの間で変換するコードが提供されます。私は、 "out"タイプマップ、すなわち関数から戻るための例を挙げます。
は考える:
sockaddr_in *make_stuff();
を我々はでそれをラップすることができます:
%typemap(jstype) sockaddr_in *make_stuff "java.net.InetSocketAddress"
%typemap(javaout) sockaddr_in *make_stuff {
long cPtr = $jnicall;
sockaddr_in s = new sockaddr_in(cPtr, true);
byte[] bytes = new byte[4];
for (int i = 0; i < 4; ++i) {
bytes[i] = (byte)s.getAddr(i);
}
java.net.InetAddress addr = null;
try {
addr = java.net.InetAddress.getByAddress(bytes);
}
catch (java.net.UnknownHostException e) {
return null;
}
return new java.net.InetSocketAddress(addr, s.getPort());
}
%immutable;
struct sockaddr_in{
%rename(family) sin_family;
short sin_family;
%extend {
unsigned short getPort() const {
return ntohs($self->sin_port);
}
char getAddr(int byte) const {
const char *ptr = reinterpret_cast<const char*>(&$self->sin_addr.s_addr);
return ptr[byte];
}
}
};
%mutable;
void do_stuff(sockaddr_in *ADDR);
我々が直接sockaddr_in
をラップする方法を指定するだけでなく、より多くのことを関数自体からの復帰を指示しました適切なJavaタイプ(%typemap(jstype)
)を使用し、変換を実行する少量のJavaを提供しました(%typemap(javaout)
)。タイプマップでも同様のことができます。これはAF_INET6
のアドレスを正しく処理しません - IPv6アドレスにはInetAddress.getByAddress()
と同等のものがありません。そのため、おそらくアサート/例外が存在するはずです。
もっと良い答えがあると確信しています。私はそれを楽しみにしています。しかし、これは最初はうまくいくようです。あなたのmodule.iで
:
%include "stdint.i"
%{
#include <arpa/inet.h>
%}
struct in_addr {
uint32_t s_addr;
};
struct sockaddr_in {
uint16_t sin_port;
struct in_addr sin_addr;
};
- 1. SWIG C++構造体からJava
- 2. JNIを使用してC構造体をJavaに転送する方法は?
- 3. SWIGを使用してC関数を処理するJavaの構造体配列へのポインタを返す
- 4. JPA(Java EE)を使用してXMLデータ構造をデータベースにマップする方法
- 5. 構造体をGoマップのキーとして使用する
- 6. C++で構造体としてkeyとvalueを使用してマップを作成する方法は?
- 7. f#からC#構造体を使用する方法#
- 8. swig typemapをC++構造体からPyLongに
- 9. Javaネイティブアクセスライブラリ(JNA)を使用して構造体にポインタを渡す
- 10. エリクシルでマップ/構造体をログに記録する方法
- 11. C++構造体ポインタを使用してデータメンバーを更新する
- 12. 構造体ポインタを使用して構造体内部の配列にアクセスする方法
- 13. C++でクロスプラットフォーム構造体を作成して使用する
- 14. 構造体を別の構造体に渡す方法
- 15. JNAを使用してネイティブメソッドから返された構造体に可変長配列をマップする方法
- 16. (C/C++)構造体を含む共用体を含む構造体...?
- 17. 構造体を使用してCで参照されるメモリ
- 18. マップに構造体を追加するC++
- 19. C++ Collections:構造体のようなマップを作成する方法
- 20. Cの構造体をインラインに割り当てる方法は?
- 21. C#で使用するためのC++データ構造体/型(構造体、列挙型)を公開するには?
- 22. 構造体からSWIG生成ゲッター/セッターを削除するJavaクラス
- 23. C構造体内の構造体内部の構造体
- 24. C#の構造体をCの構造体に変換するには?
- 25. C++ ASM ASMで構造体メンバを使用する方法をインライン?
- 26. C++構造体の初期化方法
- 27. qsort()とCの構造体の使用
- 28. Golang:複数のソートパラメータを使用して構造体をソートする方法は?
- 29. JNAを使用してcom.sun.jna.StructureをC言語で構造体Cに渡す方法
- 30. C言語を使用して構造体にchar名をソートする
既存の 'java.net.InetAddress'クラスと互換性を持たせたいのですか、' sockaddr_in'を使用可能なインタフェースでラップするだけですか? – Flexo
私は使用可能なインターフェイスでそれをラップしたいと思っています... – c12