2011-04-22 4 views
0

C 선언을 처리하는 방법 :C :이 방법을

struct t_name 
{ 
    char first_name[128]; 
    char nickname[128]; 
    int32_t words[7]; 
    uint16_t parts_of_speech[7]; 
    uint32_t language; 
    bool has_name; 
}; 

char* Translation_TranslateNameEnglish(DFHackObject* trans, const t_name* name); 

나는 C#에서 그 일을하고 어떻게 :

[StructLayout(LayoutKind.Sequential), Serializable] 
public struct DFName 
{ 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
    public string FirstName; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
    public string NickName; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] 
    public int[] Words; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] 
    public ushort[] PartsOfSpeech; 
    public uint Language; 
    public bool HasName; 
} 

[DllImport(DllName)] 
public static extern string Translation_TranslateNameEnglish(IntPtr ptr, ref DFName name); 

콜 :

DFHack.Translation_TranslateNameEnglish(translation, ref name) 

작업을 첫 번째 매개 변수로 IntPtr 아무 문제가, 나는 비슷한 호출에서 일하고있다. DFName 구조체는 다른 호출로 채워지며 유효한 데이터를 포함합니다. 그러나 TranslateNameEnglish를 호출하면 작동하지 않는 항목이 있습니다. 그 라인이 실행되면 나는 "보호 된 메모리를 읽거나 쓰려고 시도했다. 이것은 종종 다른 메모리가 손상되었다는 표시이다." 내가 뭘 잘못 했니?

중요한 부분을 언급하는 것을 잊었습니다. DFName 구조체가 다른 구조체의 일부로 검색되었습니다. 방법

public static extern int Creatures_ReadCreature(IntPtr ptr, uint index, out DFCreature creature); 
+0

동일한 이메일/OpenID를 사용하여 동일한 사람으로 로그인하면 답변을 수정할 수 있습니다. – abatishchev

답변

0

으로 검색됩니다

[StructLayout(LayoutKind.Sequential), Serializable] 
public struct DFCreature 
{ 
// Snip 
    public DFName Name; 
// Snip 
} 

은 'C'코드 sizeof(t_name)이 C# 코드에서 Marshal.SizeOf(typeof(DFName))과 같은 것을 절대적으로 확신합니다. 동일하지 않으면 C 코드의 패킹 옵션과 p/invoke 시그니처의 Ansi/Unicode 옵션을 살펴보십시오.

업데이트 : 실제로 여기를 확인하면 MS C 컴파일러가 기본 패킹 옵션으로 실행되고있는 한 괜찮습니다.하지만 변경된 경우 사용자 환경에서 확인할 가치가 있습니다.

0

예, "보호 된 메모리를 읽거나 쓰려고 시도했습니다. 이것은 종종 다른 메모리가 손상되었음을 나타냅니다." 예상되는 결과입니다. 이것은 함수 내에서 문자열 값을 반환하려고하기 때문에 발생합니다. 이 경우 .NET Framework는 문자열 객체를 만들고 CoTaskMemFree 함수를 사용하여 함수에서 문자열을 가져온 메모리를 확보하려고합니다. 내가 알기로는이 메모리를 CoTaskMemAlloc으로 할당하지 않았으므로 예외가 발생했습니다. 이를 방지하기 위해 당신은 IntPtr입니다 반환하여 C#의 함수 프로토 타입을 변경해야합니다 :

[DllImport(DllName)] 
public static extern IntPtr Translation_TranslateNameEnglish(IntPtr ptr, ref DFName name); 

을 그리고 당신은 당신이 아래처럼 할 수 있습니다

string result = Marshal.PtrToStringAnsi(DFHack.Translation_TranslateNameEnglish(translation, ref name); 

그것은 또한 당신을 위해 유용 할 수 있습니다
[편집] - Marshaling unmanaged char** to managed string[]

+0

불행히도 귀하의 방법과 방법 모두 기사에서 설명하는 동일한 예외가 발생합니다 – Patrick

+0

@ 패트 릭 : 흠, 어떤 유형의'이름'있어? 그것을 위해 StringBuilder를 사용해보십시오. 이게 도움이되지 않는다면 지금은 더 이상 추측 할 수 없습니다. –

관련 문제