2016-08-30 22 views
1

bindingをjnaで作成した後、openvr samplejoglに移植します。C++でcharポインタからJava文字列を取得する方法

最後に(コントローラとトラッキング基地局をレンダリングする前に)、C言語のcharポインタをJavaのStringに変換しようとしました。

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; 
} 

GetStringTrackedDevicePropertyhere

/** 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); 

私は、第1の基準を作成し、それから、実際のアレイ。

public interface GetStringTrackedDeviceProperty_callback extends Callback { 

    int apply(int unDeviceIndex, int prop, Pointer pchValue, int unBufferSize, IntBuffer pError); 
}; 

CharArrayクラス、がらくたの試みhere

applyhere)がある

しかしhere、私は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; 
} 

何か案は?

+1

あなたのコードはCではなく、Cです。これらは異なる言語であり、その違いは重要です。 –

+0

また、Javaがどこに入ってくるのかわかりません。 Javaと直接インタフェースすることを意味するのであれば、JNIが必要です.JNIはどこにもありません。仲介ファイルやパイプを介してのように、よりゆるやかなやりとりを念頭に置いている場合は、それらの詳細が重要です。 –

+0

うん、あなたは正しいですジョン、ありがとう、私はそれを修正しました。Javaにはバインディングが付属していますが、私も今すぐ追加しました。 – elect

答えて

1

私は、JavaにCおよびC++コードのいくつかの移植を行ってきた、そしてそれはおそらく恐ろしくハックですが、私は原始的intまたはchar*/Stringへのポインタが必要なケースを解決するために作ってみた最高単一のプロパティを持つ小さなラッパークラスを作成し、そのオブジェクトを関数に渡し、必要に応じてプロパティを変更し、関数呼び出しの後に新しい値を取得することです。だから、のようなもの:

public class StringPointer { 
    public String value = ""; 
} 

StringPointer pchBuffer = new StringPointer(); 
unRequiredBufferLen = pHmd.GetStringTrackedDeviceProperty(unDevice, prop, pchBuffer, unRequiredBufferLen, peError); 
String sResult = pchBuffer.value; 

、それはあなたのコードは、関数呼び出しの後char*でやっていることだからGetStringTrackedDeviceProperty()この場合

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

の内側に、あなたは、Stringを使用することができますが、実際にそれであれば実際にはchar[]である必要があります、あなたはchar[] pchBuffer = new char[unRequiredBufferLen];を作成し、それを関数に渡すことができます。 C++でchar*を使用していたのと同じようになり、関数の終了後に配列内で行った変更はすべて表示され、String sResult = new String(pchBuffer);を実行することもできます。

+0

面白いアイデア、試してみましょう – elect

+0

それで、最初の方法については、 GetStringTrackedDeviceProperty'は、 'extends Callback'という型の' interface GetStringTrackedDeviceProperty_callback'型であるため、本体を持つことはできません。しかし、私はまた第2のヒントを試しました。引数をjna 'Pointer'から' char [] 'に変更することで動作しますが、C言語では奇妙な結果を得ました。+ + lighthouse' ... – elect

+1

おそらくC++の部分はシングルバイト文字を使用しています。個々の 'char'を個々のバイトに分割すると、正しい答えが得られますか? – jonhopkins

関連する問題