如何在c++中从char指针获得Java字符串

How to get a Java string from a char pointer in C++

本文关键字:Java 字符串 指针 char c++ 中从      更新时间:2023-10-16

在使用jna创建绑定之后,我正在将openvr示例移植到jogl。

几乎在最后(在渲染控制器和跟踪基站之前),我试图将C中的char指针转换为Java中的String。

c++代码:

//-----------------------------------------------------------------------------
// Purpose: Helper to get a string from a tracked device property and turn it
//          into a std::string
//-----------------------------------------------------------------------------
std::string GetTrackedDeviceString( vr::IVRSystem *pHmd, vr::TrackedDeviceIndex_t unDevice, vr::TrackedDeviceProperty prop, vr::TrackedPropertyError *peError = NULL )
{
    uint32_t unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty( unDevice, prop, NULL, 0, peError );
    if( unRequiredBufferLen == 0 )
        return "";
    char *pchBuffer = new char[ unRequiredBufferLen ];
    unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty( unDevice, prop, pchBuffer, unRequiredBufferLen, peError );
    std::string sResult = pchBuffer;
    delete [] pchBuffer;
    return sResult;
}

GetStringTrackedDeviceProperty此处:

/** Returns a string property. If the device index is not valid or the property is not a string type this function will 
* return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing
* null. Strings will generally fit in buffers of k_unTrackingStringSize characters. */
virtual uint32_t GetStringTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ) = 0;

这里的VR_OUT_STRING()定义为:

# define VR_CLANG_ATTR(ATTR)
#define VR_OUT_STRING() VR_CLANG_ATTR( "out_string: ;" )

我已经做了类似的事情,我不得不调用一个函数,期望指向TrackedDevicePose_t结构数组的指针:

private TrackedDevicePose_t.ByReference trackedDevicePosesReference = new TrackedDevicePose_t.ByReference();
public TrackedDevicePose_t[] trackedDevicePose
            = (TrackedDevicePose_t[]) trackedDevicePosesReference.toArray(VR.k_unMaxTrackedDeviceCount);

我首先创建了引用,然后从它创建了实际的数组。

但是这里我不能有一个类来扩展char数组。

private String getTrackedDeviceString(IVRSystem hmd, int device, int prop, IntBuffer propError) {
    int requiredBufferLen = hmd.GetStringTrackedDeviceProperty.apply(device, prop, Pointer.NULL, 0, propError);
    if(requiredBufferLen == 0) {
        return "";
    }

    CharArray.ByReference charArrayReference = new CharArray.ByReference();
    char[] cs = charArrayReference.toArray(requiredBufferLen);
    return null;
}

其中apply(这里)为:

public interface GetStringTrackedDeviceProperty_callback extends Callback {
    int apply(int unDeviceIndex, int prop, Pointer pchValue, int unBufferSize, IntBuffer pError);
};

CharArray类,这里的垃圾尝试

任何想法?

我已经完成了一些C和c++代码到Java的移植,虽然它可能是可怕的hackky,最好的我已经提出解决的情况下,一个intchar*/String的指针需要一个函数调用,是创建一个小包装器类与一个单一的属性,传递该对象到函数,根据需要改变属性,并在函数调用后检索新值。比如:

public class StringPointer {
    public String value = "";
}
StringPointer pchBuffer = new StringPointer();
unRequiredBufferLen = pHmd.GetStringTrackedDeviceProperty( unDevice, prop, pchBuffer, unRequiredBufferLen, peError );
String sResult = pchBuffer.value;

GetStringTrackedDeviceProperty()

...
pchValue.value = "some string";
...

在这种情况下,您可以使用String,因为这是您的代码在函数调用后对char*所做的事情,但如果它实际上确实需要char[],您可以创建char[] pchBuffer = new char[unRequiredBufferLen];并将其传递给函数。这就像你在c++中使用char*一样,在函数结束后,你在数组内所做的任何更改都将是可见的,你甚至可以做String sResult = new String(pchBuffer);