기존 VB6 응용 프로그램을 C #으로 변환하려고합니다. 응용 프로그램은 VB6로도 작성되었으며 ActiveX DLL 인 API를 사용해야합니다. .NET Interop 기능을 사용하여이 API를 C #에서 사용할 수 있도록 래핑하고 있습니다.
문제는 바이트 배열을 가져온 다음 RtlMoveMemory ()를 사용하여 Struct로 이동하는 코드입니다. 아래에 제공된 C # 코드를 사용하면 System.ArgumentException "값이 예상 범위에 속하지 않습니다"예외가 발생합니다. 이 구현의 다양한 순열과 일부 마샬링을 시도했지만이 영역에 대한 내 심도를 약간 벗어났습니다. 내가 시도한 모든 것이 어떤 형태의 처리되지 않은 예외를 초래했습니다.
RtlMoveMemory ()를 사용하는 솔루션은 괜찮지 만 Marshalling을 사용하는 솔루션이 더 좋습니다. 바라건대 점을 연결하는 문제 일뿐입니다.
VB6 코드 :
Public Declare Sub MoveIt Lib "kernel32.dll" Alias "RtlMoveMemory" (dest As Any, src As Any, ByVal bytes As Long)
Type IntEventStruct
TTag As Double
quality As Long
Value As Single
End Type
Dim byteBuff(PACKETSIZE - 1) As Byte
Dim dEvent As IntEventStruct
Call DWApi.ReadEvent(code, DBIndex, TTStr, interval, byteBuff, errMsg)
Call MoveIt(dEvent, byteBuff(0), Len(dEvent))
C # 코드 :
[DllImport("kernel32.dll", EntryPoint="RtlMoveMemory")]
static extern void MoveIt(Object Destination, Object Source, long Length);
public struct ReadEventStruct
{
public double TimeTag;
public int Quality;
public float Value;
}
byte[] byteBuff = new byte[BUFFER_SIZE];
ReadEventStruct dwRead = new ReadEventStruct();
this.dw.ReadEvent(pt.Plant, pt.Index, pt.Time, pt.Interval, ref byteBuff, ref errMsg);
MoveIt(dwRead, byteBuff, Marshal.SizeOf(dwRead));
ReadEvent () 관련 API 문서 (소스 코드에 대한 액세스 권한이 없습니다) :
This routine retrieves process data for a specified point at a single time.
Calling convention:
Call DWPCAPI.ReadEvent(Plant As String, _
iChannel As Long, _
StartT As String, _
Interval as Single, _
Buffer() As Byte, _
ErrMsg As String)
Buffer( ): Byte buffer containing returned data.
내 원래 질문에 대한 의견에 가장 좋은 답변이 제공되었습니다. BitConverter
마샬링 대신 클래스를 사용하는 것이 좋지만 주석 작성자가 답변으로 제공하지 않았기 때문에 다음과 같습니다.
ReadEventStruct dwRead = new ReadEventStruct();
Array buffer = new byte[BUFFER_SIZE];
this.dw.ReadEvent(pt.Plant, pt.Index, pt.Time, pt.Interval, ref buffer, ref errMsg);
byte[] byteBuffer = (byte[])buffer; // Convert to byte[] so BitConverter class can be used
dwRead.TimeTag = BitConverter.ToDouble(byteBuffer, 0); // First 8 bytes are TimeTag (double)
dwRead.Quality = BitConverter.ToInt32(byteBuffer, 8); // Next 4 bytes are Quality (integer)
dwRead.Value = BitConverter.ToSingle(byteBuffer, 12); // Last 4 bytes are Value (float)
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다