Java 获取jstring/char*的长度?

Java 获取jstring/char*的长度?,java,c++,c,java-native-interface,Java,C++,C,Java Native Interface,这是我的JNI C代码: JNIEXPORT jint JNICALL Java_org_avuna_httpd_util_CLibJNI_bind(JNIEnv * this, jclass cls, jint sockfd, jint family, jstring path, jint len) { struct sockaddr_un sun; sun.sun_family = family; const char *npath = (*this)->Get

这是我的JNI C代码:

JNIEXPORT jint JNICALL Java_org_avuna_httpd_util_CLibJNI_bind(JNIEnv * this, jclass cls, jint sockfd, jint family, jstring path, jint len) {
    struct sockaddr_un sun;
    sun.sun_family = family;
    const char *npath = (*this)->GetStringUTFChars(this, path, 0);
    sun.sun_path = npath;
    return bind(sockfd, sun, sizeof(&npath));
}
我只是猜了一下如何获得长度,但没有成功(
sizeof(&npath)
)。我对C不是很精通,但我认为有一种方法可以获得jstring的长度


Google什么也不产生,我缺少什么基本的东西?

因为变量的类型是
const char*
它表明它是一个
nul
终止的字符串,因此

size_t length = strlen(npath);
应该足够了

尽管您对
bind()
的调用是错误的,但您应该传递地址结构的大小,以便

return bind(sockfd, sun, sizeof(sun));

应该是正确的。

因为变量的类型是
const char*
这表明它是一个
nul
终止字符串,因此

size_t length = strlen(npath);
应该足够了

尽管您对
bind()
的调用是错误的,但您应该传递地址结构的大小,以便

return bind(sockfd, sun, sizeof(sun));

应该是正确的。

首先,内存泄漏。必须使用
ReleaseStringUTFChars()
释放由
GetStringUTFChars()
返回的
char*
指针,但您没有这样做

其次,
bind()
希望您指定
sockaddr\u un
结构的字节大小,而不是
npath
的字符长度。另外,
bind()
的第二个参数需要一个
sockaddr*
指针作为输入

第三,
sockaddr\u un::sun\u path
是一个
char[]
数组,您不能将
char*
指针分配给它。你必须复制被指向的内容

试试这个:

JNIEXPORT jint JNICALL Java_org_avuna_httpd_util_CLibJNI_bind(JNIEnv * this, jclass cls, jint sockfd, jint family, jstring path, jint len)
{
    struct sockaddr_un sun;
    memset(&sun, 0, sizeof(sun));
    sun.sun_family = family;
    const char *npath = (*this)->GetStringUTFChars(this, path, 0);
    strncpy(sun.sun_path, npath, UNIX_PATH_MAX);
    (*this)->ReleaseStringUTFChars(this, path, npath);
    return bind(sockfd, (struct sockaddr *) &sun, sizeof(sun));
}
话虽如此,
sockaddr\u un
始终对其系列使用
AF\u UNIX
,因此将
系列作为输入值传递是没有意义的。如果需要传入不同的
系列
值,则需要为每个
系列
使用不同的
sockaddr\ux…
结构,例如:

JNIEXPORT jint JNICALL Java_org_avuna_httpd_util_CLibJNI_bind(JNIEnv * this, jclass cls, jint sockfd, jint family, jstring path, jint len)
{
    switch (family)
    {
        case AF_UNIX:
        {
            struct sockaddr_un sun;
            memset(&sun, 0, sizeof(sun));
            sun.sun_family = AF_UNIX;
            const char *npath = (*this)->GetStringUTFChars(this, path, 0);
            strncpy(sun.sun_path, npath, UNIX_PATH_MAX);
            (*this)->ReleaseStringUTFChars(this, path, npath);
            return bind(sockfd, (struct sockaddr *) &sun, sizeof(sun));
        }

        case AF_INET:
        {
            struct sockaddr_in sin;
            memset(&sin, 0, sizeof(sin));
            sin.sin_family = AF_INET;
            const char *npath = (*this)->GetStringUTFChars(this, path, 0);
            inet_pton(AF_INET, npath, &sin.sin_addr);
            sin.sin_port = 0;
            (*this)->ReleaseStringUTFChars(this, path, npath);
            return bind(sockfd, (struct sockaddr *) &sin, sizeof(sin));
        }

        case AF_INET6:
        {
            struct sockaddr_in6 sin;
            memset(&sin, 0, sizeof(sin));
            sin.sin6_family = AF_INET6;
            const char *npath = (*this)->GetStringUTFChars(this, path, 0);
            inet_pton(AF_INET6, npath, &sin.sin6_addr);
            sin.sin6_port = 0;
            (*this)->ReleaseStringUTFChars(this, path, npath);
            return bind(sockfd, (struct sockaddr *) &sin, sizeof(sin));
        }

        // and so on ...
    }

    return -1;
}

首先,内存泄漏。必须使用
ReleaseStringUTFChars()
释放由
GetStringUTFChars()
返回的
char*
指针,但您没有这样做

其次,
bind()
希望您指定
sockaddr\u un
结构的字节大小,而不是
npath
的字符长度。另外,
bind()
的第二个参数需要一个
sockaddr*
指针作为输入

第三,
sockaddr\u un::sun\u path
是一个
char[]
数组,您不能将
char*
指针分配给它。你必须复制被指向的内容

试试这个:

JNIEXPORT jint JNICALL Java_org_avuna_httpd_util_CLibJNI_bind(JNIEnv * this, jclass cls, jint sockfd, jint family, jstring path, jint len)
{
    struct sockaddr_un sun;
    memset(&sun, 0, sizeof(sun));
    sun.sun_family = family;
    const char *npath = (*this)->GetStringUTFChars(this, path, 0);
    strncpy(sun.sun_path, npath, UNIX_PATH_MAX);
    (*this)->ReleaseStringUTFChars(this, path, npath);
    return bind(sockfd, (struct sockaddr *) &sun, sizeof(sun));
}
话虽如此,
sockaddr\u un
始终对其系列使用
AF\u UNIX
,因此将
系列作为输入值传递是没有意义的。如果需要传入不同的
系列
值,则需要为每个
系列
使用不同的
sockaddr\ux…
结构,例如:

JNIEXPORT jint JNICALL Java_org_avuna_httpd_util_CLibJNI_bind(JNIEnv * this, jclass cls, jint sockfd, jint family, jstring path, jint len)
{
    switch (family)
    {
        case AF_UNIX:
        {
            struct sockaddr_un sun;
            memset(&sun, 0, sizeof(sun));
            sun.sun_family = AF_UNIX;
            const char *npath = (*this)->GetStringUTFChars(this, path, 0);
            strncpy(sun.sun_path, npath, UNIX_PATH_MAX);
            (*this)->ReleaseStringUTFChars(this, path, npath);
            return bind(sockfd, (struct sockaddr *) &sun, sizeof(sun));
        }

        case AF_INET:
        {
            struct sockaddr_in sin;
            memset(&sin, 0, sizeof(sin));
            sin.sin_family = AF_INET;
            const char *npath = (*this)->GetStringUTFChars(this, path, 0);
            inet_pton(AF_INET, npath, &sin.sin_addr);
            sin.sin_port = 0;
            (*this)->ReleaseStringUTFChars(this, path, npath);
            return bind(sockfd, (struct sockaddr *) &sin, sizeof(sin));
        }

        case AF_INET6:
        {
            struct sockaddr_in6 sin;
            memset(&sin, 0, sizeof(sin));
            sin.sin6_family = AF_INET6;
            const char *npath = (*this)->GetStringUTFChars(this, path, 0);
            inet_pton(AF_INET6, npath, &sin.sin6_addr);
            sin.sin6_port = 0;
            (*this)->ReleaseStringUTFChars(this, path, npath);
            return bind(sockfd, (struct sockaddr *) &sin, sizeof(sin));
        }

        // and so on ...
    }

    return -1;
}

关于jstring的长度,需要的是GetStringUTFLength


这应该比在以null结尾的字符*上调用strlen更有效,因为我认为它不需要搜索最终的null。

关于jstring的长度,需要的是GetStringUTFLength


这应该比在以null结尾的字符*上调用strlen更有效,因为我认为它不需要搜索最终的null。

不,
sizeof()
不会给出字符串的长度,而是类型的大小,你确定
(*This)->
?@iharob我在网上找到它,测试将显示它是否好。您可以检查
JNIEnv
是如何定义的,以及它是否是一个指针
typedef
,这意味着
(*this)
是有意义的。
JNIEnv
确实是一个指针:
typedef const struct jniativeinterface*JNIEnv
因此JNI函数有效地将
JNITINAVEINTERFACE**
作为输入,因此
(*此)->
是正确的语法。不,
sizeof()
不会给出字符串的长度,而是类型的大小,你确定
(*此)->
?@iharob我在网上找到它,测试将显示它是否好。您可以检查
JNIEnv
是如何定义的,以及它是否是一个指针
typedef
,这意味着
(*this)
是有意义的。
JNIEnv
确实是一个指针:
typedef const struct jniativeinterface*JNIEnvJNITINAVEINTERFACE**
作为输入,因此
(*this)->
使用的语法是正确的。
bind()
的第二个参数需要一个
sockaddr*
指针作为输入:
bind(sockfd,(struct sockaddr*)&sun,sizeof(sun))
bind()的第二个参数
需要一个
sockaddr*
指针作为输入:
bind(sockfd,(struct sockaddr*)&sun,sizeof(sun))