C+ C ++ 구조물 배열 원수
-
06-07-2019 - |
문제
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;
}