SWIG를 통해 Java를 사용하여 호출하고자하는 C 함수가 있지만 sockaddr_in C 구조를 처리하는 방법이 확실하지 않습니다. 누구나 내가 sockaddr_in을 어떻게 처리 할 수 있는지에 대한 예제가 있습니까?Sockaddr_in C 구조를 SWIG를 사용하여 Java로 매핑
답변
지금 약간 오래된 보이지만 swig.org에 sockaddr_in
포장에 관한 기사가 사실이있다.
기본적으로 Java에서 전달하기 쉬운 것으로 채워야하는 값에 대한 인수를 취하여 새로운 sockaddr_in
을 만드는 함수를 작성했습니다. 이 링크 된 문서의 약간 업데이트, 손질 버전입니다 : 우리가 느낄 수있는 대신 java.net.InetSocketAddress
을 사용하는 타입 맵을 작성할 수 있습니다
%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);
하지만 꿀꺽 꿀꺽로이 포장의 더 좋은 방법이있다 "훨씬 더 인터페이스의 자바 측 "자연 :
%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
를 만드는 결과를 사용합니다.
주 :
- 내가 여기 바이트 순서를 가지고 있는지 100 % 아니에요 우리는 제대로 너무 AF_INET6를 지원한다고
- - 우리가 볼 수있는 주어진
InetSocketAddress
을 검사해야하는 것 어떤 하위 클래스는 typemap 자체에있다. - 입력란에
out
이 없습니다. 이것은 기본적으로 역순입니다. JNI 코드는 새로운 Java 객체를 생성합니다. - 어설 션은 꽤 추합니다.
완성도를 들어도 더 JNI를 포함하지 않는이, 포장,하지만 자바의 조금 쓰기의 세 번째 가능한 방법이있다. 우리가하는 일은 SWIG가 첫 번째 예제에서와 같이 struct sockaddr
을 랩핑 한 다음 sockaddr
을 사용하는 랩핑 된 함수를 가지고 있고 java.net.InetSocketAddress
오브젝트를 여전히 반환하고 둘 사이의 변환을위한 코드를 제공합니다. "out"typemap, 즉 함수에서 반환하는 예제를 보여 드리겠습니다.
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)
). 우리는 typemap에서도 비슷하게 할 수 있습니다. 이것은 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. C# sockaddr to sockaddr_in
- 2. C++ - SOCKADDR_IN 초기화
- 3. SWIG를 사용하여 PHP에 C++ 클래스 통합하기
- 4. SWIG를 사용하여 Python에서 C++ typedef에 액세스
- 5. SWIG를 사용하여 옥타브의 C++ API를 래핑
- 6. SWIG를 통한 Wrap C 콜백
- 7. SWIG를 사용하여 C++ API를 통해 C 래퍼를 생성하려면 어떻게해야합니까?
- 8. SWIG를 사용하여 PHP C/C++ 확장 모듈 생성
- 9. SWIG를 사용하여 C++에서 C#으로 포인터 반환
- 10. 메모리 매핑 파일 - 파일이 아닌 구조를 매핑 하시겠습니까?
- 11. CFDataRef에서 sockaddr_in 받기
- 12. SWIG를 사용하여 C에서 객체 지향 API 만들기
- 13. Java로 연결된 목록 데이터 구조를 만들려면 어떻게해야합니까?
- 14. SWIG를 사용하여 열거 형 멤버를 열거하는 방법
- 15. SWIG를 사용하여 Perl로 이진 데이터 이동/
- 16. SWIG를 사용하여 배열과 상호 작용하는 올바른 방법
- 17. Python에서 Swig를 사용하여 float **를 사용하는 방법?
- 18. SWIG를 통한 C++ 및 Java GUI 링크
- 19. swig를 사용하여 C++ 용 PHP 인터페이스를 생성하는 방법
- 20. SWIG를 사용하여 Python __init__ 함수에서 C++ 팩토리 메서드를 래핑하는 방법
- 21. SWIG를 사용하여 C++ 응용 프로그램에 Ruby를 포함 하시겠습니까?
- 22. SWIG를 사용하는 DCMTK 라이브러리 용 C# 래퍼
- 23. SWIG를 사용하여 C에서 Perl 해시를 작성하려면 어떻게해야합니까?
- 24. SWIG를 사용하여 중첩 된 공용 멤버에 액세스하는 방법?
- 25. ctypes와 swig를 결합
- 26. C++ 암호화를 Java로 변환
- 27. C 포인터를 Java로 변환
- 28. JNI를 사용하여 C 구조체를 Java로 전송하는 방법은 무엇입니까?
- 29. long을 사용하여 JNI에서 Java로 포인터를 전달합니다.
- 30. C++에서 Java로 객체 반환
기존의'java.net.InetAddress' 클래스와 호환 가능하게 만드시겠습니까, 아니면'sockaddr_in'을 사용 가능한 인터페이스로 감싸 주시겠습니까? – Flexo
사용 가능한 인터페이스로 포장하고 싶습니다 ... – c12