如何从 C++ 中的字符指针获取 Java 字符串
How to get a Java string from a char pointer in C++
我正在用 jna 移植 openvr sample to jogl, after we created the binding。
几乎在最后(在渲染控制器和跟踪基站之前),我在尝试将 C 中的字符指针转换为 Java 中的字符串时遇到了困难。
C++代码here:
//-----------------------------------------------------------------------------
// 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
here:
/** 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()
定义 here 为:
# 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);
我首先创建了引用,然后从中创建了实际的数组。
但是here我不能class扩展字符数组..
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
(here) 是:
public interface GetStringTrackedDeviceProperty_callback extends Callback {
int apply(int unDeviceIndex, int prop, Pointer pchValue, int unBufferSize, IntBuffer pError);
};
CharArray class,废话尝试 here
有什么想法吗?
我已经完成了一些 C 和 C++ 代码到 Java 的移植,虽然它可能非常 hacky,但我想出的最好的办法是解决指向 [=12= 的指针的情况] 原语或 char*
/String
是函数调用所必需的,是用单个 属性 创建一个小包装器 class,将该对象传递给函数,更改属性 根据需要,并在函数调用后检索新值。所以像:
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*
执行的操作,但如果它实际上确实需要 [=18] =],你可以只创建 char[] pchBuffer = new char[unRequiredBufferLen];
并将其传递给函数。就像您在 C++ 中使用 char*
一样,您在数组中所做的任何更改在函数结束后都将可见,您甚至可以执行 String sResult = new String(pchBuffer);
.
我正在用 jna 移植 openvr sample to jogl, after we created the binding。
几乎在最后(在渲染控制器和跟踪基站之前),我在尝试将 C 中的字符指针转换为 Java 中的字符串时遇到了困难。
C++代码here:
//-----------------------------------------------------------------------------
// 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
here:
/** 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()
定义 here 为:
# 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);
我首先创建了引用,然后从中创建了实际的数组。
但是here我不能class扩展字符数组..
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
(here) 是:
public interface GetStringTrackedDeviceProperty_callback extends Callback {
int apply(int unDeviceIndex, int prop, Pointer pchValue, int unBufferSize, IntBuffer pError);
};
CharArray class,废话尝试 here
有什么想法吗?
我已经完成了一些 C 和 C++ 代码到 Java 的移植,虽然它可能非常 hacky,但我想出的最好的办法是解决指向 [=12= 的指针的情况] 原语或 char*
/String
是函数调用所必需的,是用单个 属性 创建一个小包装器 class,将该对象传递给函数,更改属性 根据需要,并在函数调用后检索新值。所以像:
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*
执行的操作,但如果它实际上确实需要 [=18] =],你可以只创建 char[] pchBuffer = new char[unRequiredBufferLen];
并将其传递给函数。就像您在 C++ 中使用 char*
一样,您在数组中所做的任何更改在函数结束后都将可见,您甚至可以执行 String sResult = new String(pchBuffer);
.