2009-12-29 2 views
3

PInvoke를 사용하여 DLL을 호출합니다. DLL 함수는 코드 페이지 437에서 C 문자열을 반환합니다.C#을 사용하여 PInvoke 문자열 마샬링에 대한 코드 페이지 지정

.Net 마샬링을 사용하여 문자열을 유니 코드로 변환 할 수 있습니까? 아니면 누군가가 DllImport() 및 MarshalAs()에 제공해야하는 매개 변수를 제안 할 수 있습니다. 변환 기능을 사용하여 유니 코드에서 출력을 얻으려면?

[DllImport("name.dll", CharSet=CharSet.Unicode) ] 
internal static extern int GetSweepParam(
    int param_num, 
    [Out,MarshalAs(UnmanagedType.LPStr)]StringBuilder param_name, 
    [Out,MarshalAs(UnmanagedType.LPStr)]StringBuilder param_units, 
    double[] values, 
    [MarshalAs(UnmanagedType.LPStr)]StringBuilder error_string 
); 

답변

3

ANSI 문자열 마샬링은 항상 시스템 기본 인코딩을 사용

는 참고로, 이것은 내가 현재 사용하고 같이 DllImport입니다. 다른 인코딩을 사용하려면 해당 문자열을 직접 마샬링 할 수 있습니다. 문자열이 관리되지 않는 함수에 의해 할당 된 경우

[DllImport("name.dll")] 
internal static extern int GetSweepParam(
    int param_num, 
    [Out]byte[] param_name, 
    [Out]byte[] param_units, 
    double[] values, 
    byte[] error_string 
); 

static void Test() 
{ 
    Encoding enc = Encoding.GetEncoding(437); 
    byte[] param_name = new byte[1000], param_units = new byte[1000]; 
    GetSweepParam(123, param_name, param_units, new double[0], enc.GetBytes("input only")); 
    string name = enc.GetString(param_name, 0, Array.IndexOf(param_name, (byte)0)); 
    string units = enc.GetString(param_units, 0, Array.IndexOf(param_units, (byte)0)); 
} 

, 당신은 그것은 IntPtr에서 마샬링 할 수 있습니다.

static unsafe string PtrToStringAnsiWithEncoding(IntPtr p) 
{ 
    int l = 0; 
    byte* bytes = (byte*)p.ToPointer(); 
    while(bytes[l] != 0) l++; 
    char* chars = stackalloc char[l]; 
    int bytesUsed, charsUsed; 
    bool completed; 
    Encoding.GetEncoding(437).GetDecoder().Convert(bytes, l, chars, l, true, out bytesUsed, out charsUsed, out completed); 
    return new string(chars, 0, charsUsed); 
}