Laden...

Wie bei UnmanagedType.ByValArray die SizeConst ändern?

Erstellt von bratbaecker vor 18 Jahren Letzter Beitrag vor 18 Jahren 4.190 Views
bratbaecker Themenstarter:in
4 Beiträge seit 2004
vor 18 Jahren
Wie bei UnmanagedType.ByValArray die SizeConst ändern?

Hallo C#-User,
meist schreibe ich Programme in VEE( das ist eine graphische Programmiersprache).
Seit der Version 7.0 kann man Funktionen aus der .NET Umgebung als Funktionen ins VEE-Programm laden.

Jetzt habe ich ein Problem und zwar möchte ich Daten aus dem AN2131SC lesen und schreiben. Das funktioniert auch, aber die Datengröße ändert sich manchmal, so das ich nicht mit festen Werten in dem Struct Bufferstruct arbeiten kann.

Jetzt meine Frage: Wie kann ich die SizeConst=256 im Struct BufferStruct variable machen. Also statt 256 soll ein int Wert (bufsize) von Main übergeben werden.

Ich denke, das geht ins eingemachte, hoffe aber auf eine Lösung!

Hier der Quellcode:

 
// created on 30.05.2005 at 18:54
// Beispiel Ezusb Funktionen 
// Autor: Jan-Peter Brandt -- my-vee.de
// Sprache: C#
//
// Warning: nosafe Mode, use at your own risk

using System;
using System.Runtime.InteropServices;

[assembly: System.Reflection.AssemblyVersion("4.0.0.1")]

namespace AN2131
{
	
	[ StructLayout( LayoutKind.Sequential )]
	public struct Overlapped
	{
		public IntPtr intrnal;
		public IntPtr internalHigh;
		public int offset;
		public int offsetHigh;
		public IntPtr hEvent;
	}
	[ StructLayout( LayoutKind.Sequential)]
	public struct RequestStruct
	{
		public byte bRequest ;
		public byte bDummy ;
		public short iValue ;
		public short iIndex ;
		public short iLenght ;
		public byte bDirection ;
		public byte bData ;
	}
	
	[ StructLayout( LayoutKind.Sequential)]
	public struct BufferStruct
	{
		[MarshalAs(UnmanagedType.ByValArray, SizeConst=256)]
		public byte[] vals ;
	}
	
	// ****************** LibWrap Class **************************************
	
	public class LibWrap
	{
		// ********************** Vaiable ************************************
		
		public IntPtr handle;
		
		const uint GENERIC_READ_WRITE = 0xC0000000;
		const uint FILE_SHARED_WRITE_READ = 3;
		const uint OPEN_EXISTING = 3;
		
		public int insize = 10  ;
		public int outsize = 0  ;
		public uint wert = 0  ;
		public uint dw = 2236436 ;     //  0x222014 IOCTL_Ezusb_Vendor_Request
		public static string DeviceName = "\\\\.\\ezusb-0";
		
		// ******************* End Variable ************************************
		
		public Overlapped over = new Overlapped();
		public RequestStruct Request = new RequestStruct();
		public BufferStruct outbuffer = new BufferStruct();
		
		// *********************** CreateFileA  mit Open()**********************
		
		[DllImport("kernel32", SetLastError=true)]
		public static extern IntPtr CreateFile(
		                                       string FileName,
		                                       uint DesiredAccess,
		                                       uint ShareMode,
		                                       uint SecurityAttributes,
		                                       uint CreationDisposition,
		                                       uint FlagsAndAttributes,
		                                       int hTemplateFile
		                                       );
		
		public bool Open(string FileName)
		{
			// open the existing file for reading
			handle = CreateFile(FileName,GENERIC_READ_WRITE,FILE_SHARED_WRITE_READ,0,OPEN_EXISTING,0,0);
			if (handle != IntPtr.Zero)
				return true;
			else
				return false;
		}
		
		// ********************** CloseHandle mit Close() ***********************
		
		[DllImport("kernel32", SetLastError=true)]
		public static extern bool CloseHandle(IntPtr hObject);  // handle to object
		
		public bool Close()
		{
			// close file handle
			return CloseHandle(handle);
		}
		
		
		// ************************ DeviceIoControl mit SenderIO *****************
		
		[DllImport ("kernel32.dll", SetLastError=true)]
		public static extern bool DeviceIoControl(
		                                          HandleRef hndRef,
		                                          uint dwIoControlCode,
		                                          ref RequestStruct IpInBuffer,
		                                          int nInBufferSize,
		                                          ref BufferStruct IpOutBuffer,
		                                          int nOutBufferSize,
		                                          ref uint BytesReturned,
		                                          ref Overlapped flag );
		
		public bool SenderIO( HandleRef hndRef)
		{
			return DeviceIoControl(hndRef,dw,ref Request,insize,ref outbuffer,outsize,ref wert,ref over);
		}
		
	}
	
	// ************************ Application Class mit Main ************************
	public class App
	{
		public static void Main()
		{
			
			string FileName = LibWrap.DeviceName ;
			LibWrap Ezusb = new LibWrap();
			
			// Code für Start - Reset USB-Programm intern
			
			Ezusb.Request.bRequest = 160 ;   // Byte 0xA0
			Ezusb.Request.bDummy = 0 ;       // Byte
			Ezusb.Request.iValue = 32658 ;   // short  0x7F92
			Ezusb.Request.iIndex = 0 ;       // short
			Ezusb.Request.iLenght = 1 ;      // short
			Ezusb.Request.bDirection = 0 ;   // Byte
			Ezusb.Request.bData = 0 ;        // Byte   0 ~ Start --- 1 ~ Reset;
			
			Ezusb.Open(FileName);
			HandleRef FileHandle = new HandleRef( Ezusb, Ezusb.handle );
			
			Ezusb.SenderIO(FileHandle);
			
			// Console.WriteLine( "Read with handle parameter: {0}", Ezusb.handle);
			
			// wenn nichts passiert, dann USB-Verbindung trennen !!
			
			Ezusb.Close();
			
		}
	}
}

C
1.215 Beiträge seit 2004
vor 18 Jahren

hi,
die doku ist da recht eindeutig - leider:
"Arrays können als UnmanagedType.ByValArray gemarshallt werden. Dazu müssen Sie das MarshalAsAttribute.SizeConst-Feld einrichten. Die Größe kann nur als Konstante eingerichtet werden..."

sieht also schlecht aus, was in strukturen eingebettete arrays betrifft.

grüsse

bratbaecker Themenstarter:in
4 Beiträge seit 2004
vor 18 Jahren

Hallo Cord Worthmann,
danke für deine Info.

Ich brauche eigentlich nur eine Lösung für die Datenausgabe aus dem DeviceIoControl (als Bufferstruct lpOutBuffer).
Wenn ich Daten hinein schreibe, dann weiß ich ja die Größe.

Wie könnte man das Problem sonst lösen?

Verallgemeinert : Byte ArrayDaten aus einer DLL auslesen

Der Datentyp ist in der MS Kernel32.dll als LPVOID beschrieben und in Basic wird er als "lpOutBuffer As ANY" benutzt.

Gruß Bratbaecker

4.221 Beiträge seit 2005
vor 18 Jahren

Guck Dir mal Marshal.PtrToStructure und Marshal.StructureToPtr an

Da musste zwar viel selber machen aber Hauptsache es tut 😁

Du erhälst dann von unmanaged den IntPtr und machst dir daraus selber wieder ein Array...

Umgekehrt gehts auch... mach dir das Array... zieh daraus den Pointer usw...

Falls es so nicht gehen sollte (würde mich erstaunen)... dann kannste immer noch direkt mit Marshal.Readxxx direkt mit offsets vom Pointer lesen...

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

C
1.215 Beiträge seit 2004
vor 18 Jahren

schau dir mal diese beispiele an...
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vcwlkunsafecodetutorial.asp

du kannst im unsafe-mode direkt mit pointern arbeiten, da ist die BufferStruct gar nicht mehr notwendig.

4.221 Beiträge seit 2005
vor 18 Jahren

Original von Cord Worthmann
schau dir mal diese beispiele an...

>

du kannst im unsafe-mode direkt mit pointern arbeiten, da ist die BufferStruct gar nicht mehr notwendig.

unsafe ist für die Toilette find ich 😜

Ich habe Twain vollständig implementiert (API-Calls bis zum Abwinken) ohne auch nur ein einziges unsafe zu verwenden.... es geht also auch ohne unsafe

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

bratbaecker Themenstarter:in
4 Beiträge seit 2004
vor 18 Jahren

Danke für die Tipps,

Hab' da mal eine Verständnisfrage zur "Toilette".
Ich benutze das Schlüsselwort unsafe nicht im Quelltext. Jetzt hatte ich mal falsche Parameterwerte übergeben und schwupps gings der Rechner aus und boote neu.

(denke, meine Aufrufe wühlen auch in der api rum)
Passiert das bei unsafe incl. dann nicht mehr, oder wie wird das genutzt?

Gruß Bratbaecker

4.221 Beiträge seit 2005
vor 18 Jahren

Es kann immer crashen wenn man API calls macht...

Das mit der Toilette war eigentlich so gemeint, dass ich es hasse, wenn dann das aufrufende Programm trusted sein muss

MSDN:

Unsafe code is in fact a "safe" feature from the perspective of both developers and users. Unsafe code must be clearly marked with the modifier unsafe, so developers can't possibly use unsafe features accidentally, and the execution engine works to ensure that unsafe code cannot be executed in an untrusted environment.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

C
1.215 Beiträge seit 2004
vor 18 Jahren

klar gehts auch (fast) immer ohne unsafe - ist aber auch gerne mal die doppelte arbeit und mehr...

grüsse

4.221 Beiträge seit 2005
vor 18 Jahren

Original von Cord Worthmann
klar gehts auch (fast) immer ohne unsafe - ist aber auch gerne mal die doppelte arbeit und mehr...

grüsse

Yep das ist so X(

und langsamer ist es auch 🙄 🙄

Aber die Gründe wieso ich trotzdem auf unsafe verzichte habe ich dargelegt.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

bratbaecker Themenstarter:in
4 Beiträge seit 2004
vor 18 Jahren

Wird's mir durchlesen,
was dahinter steckt und dann spül ich den Klopps runter.

🙂

4.221 Beiträge seit 2005
vor 18 Jahren

Hände waschen nicht vergessen ..... Infotainment lässt grüssen 😁

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...