문제

C ++에 다음 구조물이 있습니다.

#define MAXCHARS 15

typedef struct 
{
    char data[MAXCHARS];
    int prob[MAXCHARS];
} LPRData;

그리고 내가 P/호출하는 함수이 구조 중 3 개 배열을 얻습니다.

void GetData(LPRData *data);

C ++에서는 다음과 같은 일을 할 것입니다.

LPRData *Results;
Results = (LPRData *)malloc(MAXRESULTS*sizeof(LPRData));
GetData( Results );

그리고 그것은 잘 작동하지만 C#에서는 작동하지 않는 것 같습니다. 나는 다음과 같은 c# struct를 만들었습니다.

public struct LPRData
{

    /// char[15]
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
    public string data;

    /// int[15]
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
    public int[] prob;
}

그리고 내가 그 중 3 개 배열을 초기화하고 (그리고 그들의 모든 하위 배열) 이것을 전달하면 다음과 같습니다.

GetData(LPRData[] data);

성공으로 돌아 오지만 LPRDATA 배열의 데이터는 변경되지 않았습니다.

나는 심지어 3 lprdata의 크기의 원시 바이트 배열을 만들고 다음과 같은 기능 프로토 타입으로 전달하려고 노력했습니다.

getData (byte [] data);

그러나이 경우 첫 번째 lprdata 구조에서 "데이터"문자열을 얻을 수 있지만 동일한 lprdata의 "prob"배열을 포함하여 그 뒤에는 아무것도 얻지 못합니다.

이것을 올바르게 처리하는 방법에 대한 아이디어가 있습니까?

도움이 되었습니까?

해결책

나는 당신의 구조물 decloration에 몇 가지 속성을 추가하려고합니다.

[StructLayout(LayoutKind.Sequential, Size=TotalBytesInStruct),Serializable]
public struct LPRData
{
/// char[15]
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public string data;

/// int[15]
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] prob;
}

*참고 TotalBytesInstruct는 변수를 나타내는 것이 아닙니다.

Jaredpar는 또한 intptr 클래스를 사용하는 것이 도움이 될 수 있다는 것이 옳습니다. 그러나 Pinvoke를 사용한 이후로 Rusty를 사용했기 때문에 아주 시간이 지났습니다.

다른 팁

포인터를 다룰 때의 한 가지 요령은 intptr을 사용하는 것입니다. 그런 다음 포인터에 Marshal.ptrtostructure를 사용하여 구조의 크기를 기준으로 증가하여 결과를 얻을 수 있습니다.

static extern void GetData([Out] out IntPtr ptr);

LPRData[] GetData()
{
    IntPtr value;
    LPRData[] array = new LPRData[3];
    GetData(out value);
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = Marshal.PtrToStructure(value, typeof(LPRData));
        value += Marshal.SizeOf(typeof(LPRData));
    }
    return array;
}

Pinvoke Interop Assistant가 도움이 될 수 있습니다. http://clrinterop.codeplex.com/releases/view/14120

GetData 매개 변수를 표시 했습니까? 외형?

배열 및 형식의 차단성이없는 유형에 적용 할 때는 비주교와 외부 공물을 결합하는 것이 특히 유용합니다. 발신자는 Callee가 두 속성을 모두 적용 할 때만 이러한 유형에 대한 변경 사항을 확인합니다.

비슷한 주제가 논의되었습니다 이 질문, 결론 중 하나는 CharSet 이름 지정된 매개 변수는 설정해야합니다 CharSet.Ansi. 그렇지 않으면, 우리는 a를 만들 것입니다 wchar_t A 대신 배열 char 정렬. 따라서 올바른 코드는 다음과 같습니다.

[Serializable]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct LPRData
{
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
    public string data;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
    public int[] prob;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top