Laden...

DLL Import die 327.te

Erstellt von Masquerader vor 18 Jahren Letzter Beitrag vor 18 Jahren 2.799 Views
M
Masquerader Themenstarter:in
31 Beiträge seit 2005
vor 18 Jahren
DLL Import die 327.te

Hallo,

wieder mal ein DLL-Problem:

Hab laut Header (C++) folgende Funktion zu importieren:


int i_PCI3001_SetBoardIntRoutineW32(
unsigned char b_BoardHandle,
unsigned char b_UserCallingMode,
unsigned long ul_GlobalBufferSize,
VOID ** ppv_UserGlobalBuffer,
void (far pascal * v_FunctionName) (unsigned char b_InterruptMask, unsigned int * pui_AnalogInputValue, unsigned char b_UserCallingMode, VOID * pv_UserSharedMemory));

Ich hab überhaupt keinen Plan, wie ich das importieren soll und vor allem wie ich drauf zugreifen soll.... Wäre schön, wenn mir da mal jemand weiterhelfen könnte.

Ach ja, was ist eigentlich ein VOID ** ?????

Vielen Dank

Masque

S
8.746 Beiträge seit 2005
vor 18 Jahren

void** kann vieles bedeuten, bei dir aber wohl ein Zeiger auf einen Zeiger (d.h. die aufgerufene Methode gibt dir einen Zeiger gefüllt zurück) (kannst du glaub ich mit "ref IntPtr" abbilden).

Hast übrigens Glück, dass der Callback die Calling-Convention Pascal hat. Es gibt keine anständige (nee, gar keine) Methode bei Callbacks was anderes als stdcall (=pascal) anzugeben. DLLImport kann man leider nicht für Delegates definieren. 🙁

Workaround ist hier eine extra Wrapper-DLL in C/C++ die von cdecl nach stdcall abbildet.

Hat MS gepennt....bzw. ist ihnen wohl nicht aufgefallen, weil Windows-intern ja auch alles stdcall ist und nicht cdecl, wie so beliebt bei C/C++-Libs.

M
Masquerader Themenstarter:in
31 Beiträge seit 2005
vor 18 Jahren

Also, ich muss mich jetzt wahrscheinlich mal als totaler Anfänger outen, aber was heißt das jetzt für mich? Wie kann/muss ich vorgehen? Bin eigentlich recht froh die anderen DLL's hingekriegt zu haben.

Über ein paar Codeschnipsel würde ich mich freuen.

Masque

S
8.746 Beiträge seit 2005
vor 18 Jahren

Probier mal das:



public delegate void CallbackDelegate(byte iMask, ref int aiValue, byte uMode, IntPtr shMemory);

[DllImport("deineDLL.dll"]
public int SetBoardIntRoutineW32(byte bHandle, byte uMode, long buffSize, ref IntPtr buffer, CallbackDelegate callback);  

Ich muss allerdings gestehen, dass mit das mit dem Buffer spanisch vorkommt. Offenbar musst du den Speicher selbst allokieren (daher auch die Übergabe der BufferSize). Dann hätte allerdings ein "void*" (und IntPtr ohne ref) ausgereicht. Hier hilft eigentlich nur die Doku weiter.

M
Masquerader Themenstarter:in
31 Beiträge seit 2005
vor 18 Jahren

Hab hier noch ein Beispiel von der Firma, von der die Karte ist. Werd aber auch nicht schlau draus.


typedef struct
{
   unsigned int ui_SaveArray [4] [16];  /* Global Buffer */
   unsigned int ui_TimerIntCpt ;        /* Timer interrupt counter */
   unsigned char b_ReceiveInterrupt ;   /* Interrupt flag */
}str_UserStruct;

str_UserStruct *ps_GlobalUserStruct;

/*
  +----------------------------------------------------------------------------+
  | Function name     : _VOID_ v_InterruptRoutine    ( BYTE_ b_BoardHandle,    |
  |                                                    BYTE_ b_InterruptMask,  |
  |                                                    PUINT_ pui_ValueArray   |
  |                                                    BYTE_ b_UserCallingMode,|
  |                                                    VOID *pv_UserShedMemory)|
  +----------------------------------------------------------------------------+
  | Task              : This function is an interrupt routine .                |
  +----------------------------------------------------------------------------+
\*/

_VOID_ v_InterruptRoutine ( BYTE_ b_BoardHandle,
			    BYTE_ b_InterruptMask,
			    PUINT_ pui_ValueArray,
			    BYTE_ b_UserCallingMode,
			    VOID *pv_UserSharedMemory )
   {
   unsigned int ui_Cpt;
   unsigned int i_Index;
   unsigned short int *pusi_Index;

   str_UserStruct *ps_UserStruct = (str_UserStruct *) pv_UserSharedMemory;
   pusi_Index = pui_ValueArray;

   if ((b_InterruptMask&2) == 2)
   {
		/* EOS interrupt Acquisition */

		for (ui_Cpt= 0;ui_Cpt< pui_ValueArray [0];ui_Cpt++)
		   ps_UserStruct->ui_SaveArray [ps_UserStruct->b_ReceiveInterrupt] [ui_Cpt] = pui_ValueArray [ui_Cpt+1];


   }

   ps_UserStruct->b_ReceiveInterrupt ++;

   }




void main(void)
   {
   int i_Cpt;
   unsigned char b_Gain [4];
   unsigned char b_Polar [4];
   unsigned char b_Channel [4];
   unsigned char b_BoardHandle;
   int i_ReturnValue;

       /****************************/
       /* Print sample information */
       /****************************/

       printf ("\n\n");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n| xPCI-3001 SAMPLE24 :                                                  |");
       printf ("\n| Cyclic acquisition without using DMA with extern trigger.             |");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n| Connection suggested : Analog : ST010                                 |");
       printf ("\n|                                 PX 901 -AG or -A                      |");
       printf ("\n|                        Digital : FB 3000                              |");
       printf ("\n|                                  ST010                                |");
       printf ("\n|                                  PX 901 -ZG or -Z                     |");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n| Required connection :                                                 |");
       printf ("\n|     Set Pin 28 to -(0V)                                               |");
       printf ("\n|     Set Pin 20,21,22,23 to 10V.                                       |");
       printf ("\n|     Set the digital input 1 on 24V.                                   |");
       printf ("\n|     Then the value to read for each input is 4095.                    |");
       printf ("\n| Unipolar mode : 0V -> 0, 10V -> 4095                                  |");
       printf ("\n| Bipolar mode : -10V -> 0, 0V -> 2047, 10V -> 4095                     |");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n| <ESC> exit sample                                                     |");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n| Press any key for start the sample                                    |");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n\n");
       getch  ();
       flushall();

       i_ReturnValue = Initialisation (&b_BoardHandle);

       /*************************/
       /* Test the return value */
       /*************************/

       switch (i_ReturnValue)
	  {
	  case 0:
	       break;

	  case -1:
	       printf ("\nInitialisation error");
	       printf ("\nError = %d. ", i_ReturnValue);
	       break;
	  } // switch (i_ReturnValue)

       if(i_ReturnValue == 0)
	  {
	  i_ReturnValue = i_PCI3001_SetBoardIntRoutineWin32(b_BoardHandle,
							     PCI3001_SYNCHRONOUS_MODE,
							      sizeof (str_UserStruct),
							      (void **) &ps_GlobalUserStruct,
							     v_InterruptRoutine);

S
8.746 Beiträge seit 2005
vor 18 Jahren

Damit wird aus spanisch wieder deutsch. Der aiValue im Callback ist ein Feld (Referenzen und Felder werden bei C/C++ teilweise gleich definiert).

Witzigerweise wird im Feld gleich die Länge kodiert (der erste Int gibt die Gesamtlänge des Feldes inkl. Längeninformationen an). Riecht nach einer internen Pascal-Implementierung.

Hier musst du also anstelle des "ref int" doch ein IntPtr definieren


public delegate void CallbackDelegate(byte iMask, IntPtr aiValue, byte uMode, IntPtr shMemory);

und selbst das Feld umkopieren, vergleichbar zum C-Code:


    for (ui_Cpt= 0;ui_Cpt< pui_ValueArray [0];ui_Cpt++)
           ps_UserStruct->ui_SaveArray [ps_UserStruct->b_ReceiveInterrupt] [ui_Cpt] = pui_ValueArray [ui_Cpt+1];

Du kannst dabei ein wenig tricksen: Hole dir am IntPtr einfach den Integer raus und stecke den Wert als Feldlänge in Marshal.Copy() wobei die Anfangsadresse um die Länge von "int" erhöht ist. Hier musst du noch ein wenig nach Integer rumcasten, weil IntPtr keine Operationen wie "+" erlaubt.

Beim Buffer ist es tatsächlich so, dass die Routine ihn allokiert. Es wird eine Referenz auf einen Zeiger übergeben (ref IntPtr ist daher ok). Da fragt man sich allerdings gleich: Wer gibt ihn frei? Aber der Code war ja glaub ich nicht vollständig....

M
Masquerader Themenstarter:in
31 Beiträge seit 2005
vor 18 Jahren

So, jetzt mal langsam... Ich hab hier ein altes VB5-Programm wo das ganze schonmal lief. Und das würde ich gern als roten Faden behalten.
Dort ist es so gemacht, dass die Funktion v_InterruptRoutine nur ein Flag setzt.

Die DLL binde ich wie folgt ein:


public delegate void CallbackRoutine(byte iMask, IntPtr aiValue, byte uMode, IntPtr shMemory);
		
[DllImport("PCI3001.DLL", EntryPoint = "i_PCI3001_SetBoardIntRoutineW32")]
static public extern int i_PCI3001_SetBoardIntRoutineW32(
byte b_BoardHandle,
byte b_UserCallingMode,
long ul_GlobalBufferSize,
ref IntPtr ppv_UserGlobalBuffer,
CallbackRoutine v_InterruptRoutine);

Gestartet wird die Funktion über:


int [] Werte = new int[100];

IntPtr pWerte = Marshal.AllocHGlobal(400);
Marshal.Copy(Uga, 0, pUga, 100);
			
					
i_ReturnValue = i_PCI3001_SetBoardIntRoutineW32(
b_BoardHandle,		                                                    PCI3001_ASYNCHRONOUS_MODE,
100,
pWerte,
v_InterruptRoutine());
			
Marshal.Copy(pWerte, Werte, 0, 100);
Marshal.FreeHGlobal(pWerte);

So. Und hier sind meine Probleme: Wie bzw. wo kann ich meine Funktion v_InterruptRoutine hinsetzen (also das Flag setzen)? Irgendwo ist da noch der Wurm drin...

Danke, dass du dir die Zeit nimmst.

Masque

PS: Nochmal der vollständige Beispiel-Code:


/*
  +-----------------------------------------------------------------------+
  | (C) ADDI-DATA GmbH          Dieselstrasse 3      D-77833 Ottersweier  |
  +-----------------------------------------------------------------------+
  | Tel : +49 (0) 7223/9493-0     | email    : [EMAIL]info@addi-data.com[/EMAIL]         |
  | Fax : +49 (0) 7223/9493-92    | Internet : [URL]http://www.addi-data.com[/URL]   |
  +-----------------------------------------------------------------------+
  | Project   : -                 | Compiler : BORLAND C / Visual C++     |
  | Modulname : SAMPLE24.C        | Version  : 5.01 / 5.0                 |
  +-------------------------------+---------------------------------------+
  | Author    : GUINOT C.         | Date     : 31.08.98                   |
  +-----------------------------------------------------------------------+
  | Description : Test the cyclic acquisition without using DMA           |
  |               with extern trigger.                                    |
  +-----------------------------------------------------------------------+
  | Used functions : - i_PCI3001_InitCompiler             (...) Windows   |
  |                  - i_PCI3001_CheckAndGetPCISlotNumber (...)           |
  |                  - i_PCI3001_SetBoardInformation      (...)           |
  |                  - i_PCI3001_SetBoardIntRoutineWin32      (...)       |
  |                  - i_PCI3001_InitAnalogInputAcquisition   (...)       |
  |                  - i_PCI3001_StartAnalogInputAcquisition  (...)       |
  |                  - i_PCI3001_StopAnalogInputAcquisition   (...)       |
  |                  - i_PCI3001_ClearAnalogInputAcquisition  (...)       |
  |                  - i_PCI3001_ResetBoardIntRoutine     (...)           |
  |                  - i_PCI3001_CloseBoardHandle         (...)           |
  +-----------------------------------------------------------------------+
  | Connection suggested : Analog : ST010                                 |
  |                                 PX 901 -AG or -A                      |
  |                        Digital : FB 3000                              |
  |                                  ST010                                |
  |                                  PX 901 -ZG or -Z                     |
  +-----------------------------------------------------------------------+
  | Required connection :                                                 |
  |     Set Pin 28 to -(0V)                                               |
  |     Set Pin 20,21,22,23 to 10V.                                       |
  |     Then the value to read for each input is 4095.                    |
  +-----------------------------------------------------------------------+
  |                             UPDATE'S                                  |
  +-----------------------------------------------------------------------+
  |   Date   |   Author  |          Description of updates                |
  +----------+-----------+------------------------------------------------+
  | 31.08.98 | GUINOT C. | -Creation                                      |
  +-----------------------------------------------------------------------+
\*/

#ifndef __BORLANDC__
  #include "..\..\PCI3001.h"
#else
  #include "..\..\..\PCI3001.h"
#endif
#include <stdio.h>
#include <conio.h>


/*
  +----------------------------------------------------------------------------+
  | Function name     : int Initialisation (unsigned char b_BoardHandle)       |
  +----------------------------------------------------------------------------+
  | Task              : This function is used to initialised the board .       |
  +----------------------------------------------------------------------------+
  | Output Parameter  : unsigned char *pb_BoardHandle : Handle of the board    |
  |                                                                            |
  +----------------------------------------------------------------------------+
  | Return Value      : 0 : OK                                                 |
  |                    -1 : ERROR                                              |
  +----------------------------------------------------------------------------+
\*/

int Initialisation(unsigned char *pb_BoardHandle)
   {
   unsigned char b_SlotNumberArray [10];
   int i_ReturnValue = 0;


      /******************************************/
      /* If windows program call the            */
      /* i_PCI3001_InitCompiler (...) function */
      /******************************************/
      #if defined (_Windows) || defined (_WINDOWS) || defined (_WIN32)
	 i_ReturnValue = i_PCI3001_InitCompiler (DLL_COMPILER_C);

      /*************************/
      /* Test the return value */
      /*************************/

      switch (i_ReturnValue)
	 {
	 case 0:
	      printf ("\ni_PCI3001_InitCompiler OK");
	      break;

	 case -1:
	      printf ("\ni_PCI3001_InitCompiler error");
	      printf ("\nError = %d. Parameter error", i_ReturnValue);
	      break;

	 default:
	      printf ("\ni_PCI3001_InitCompiler error");
	      printf ("\nError = %d", i_ReturnValue);
	      break;
	 } // switch (i_ReturnValue)
   #endif

   if(i_ReturnValue == 0)
      {

      /***************************************/
      /* Check all xPCI-3001 and return the  */
      /* slot number of each xPCI-3001 board */
      /***************************************/

      i_ReturnValue = i_PCI3001_CheckAndGetPCISlotNumber (b_SlotNumberArray);

      /*************************/
      /* Test the return value */
      /*************************/

      switch (i_ReturnValue)
	 {
	 case 0:
	      printf ("\ni_PCI3001_CheckAndGetPCISlotNumber OK");
	      printf ("\nNo xPCI-3001 board found");
	      break;

	 case -1:
	      printf ("\ni_PCI3001_CheckAndGetPCISlotNumber error");
	      printf ("\nError = %d. Can not open Windows NT/95 driver", i_ReturnValue);

	 default:
	      printf ("\ni_PCI3001_CheckAndGetPCISlotNumber OK");
	      printf ("\nFound %d board(s)", i_ReturnValue);
	 } // switch (i_ReturnValue)

      /*************************************/
      /* Test if one xPCI-3001 board found */
      /*************************************/

      if(i_ReturnValue > 0)
	 {

	 /************************/
	 /* Get the board handle */
	 /************************/
	 i_ReturnValue = i_PCI3001_SetBoardInformation(b_SlotNumberArray[0],16,pb_BoardHandle);

	 /*************************/
	 /* Test the return value */
	 /*************************/

	 switch (i_ReturnValue)
	    {
	    case 0:
		 printf ("\ni_PCI3001_SetBoardInformation OK");
		 break;

	    case -1:
		 printf ("\ni_PCI3001_SetBoardInformation error");
		 printf ("\nError = %d. Not available slot number", i_ReturnValue);
		 break;

	    case -2:
		 printf ("\ni_PCI3001_SetBoardInformation error");
		 printf ("\nError = %d. Board not present", i_ReturnValue);
		 break;

	    case -3:
		 printf ("\ni_PCI3001_SetBoardInformation error");
		 printf ("\nError = %d. No handle is available for the board", i_ReturnValue);
		 break;

	    case -4:
		 printf ("\ni_PCI3001_SetBoardInformation error");
		 printf ("\nError = %d. Can not open the Windows NT/95 driver", i_ReturnValue);
		 break;

	    default:
		 printf ("\ni_PCI3001_SetBoardInformation error");
		 printf ("\nError = %d", i_ReturnValue);
		 break;
	    } // switch (i_ReturnValue)


	 if(i_ReturnValue == 0)
	    return(0); /* OK */
	 else
	    return(-1); /* ERROR */
	 }
      else
	 return(-1); /* ERROR */
      }
   else
       return(-1); /* ERROR */
   }

typedef struct
{
   unsigned int ui_SaveArray [4] [16];  /* Global Buffer */
   unsigned int ui_TimerIntCpt ;        /* Timer interrupt counter */
   unsigned char b_ReceiveInterrupt ;   /* Interrupt flag */
}str_UserStruct;

str_UserStruct *ps_GlobalUserStruct;

/*
  +----------------------------------------------------------------------------+
  | Function name     : _VOID_ v_InterruptRoutine    ( BYTE_ b_BoardHandle,    |
  |                                                    BYTE_ b_InterruptMask,  |
  |                                                    PUINT_ pui_ValueArray   |
  |                                                    BYTE_ b_UserCallingMode,|
  |                                                    VOID *pv_UserShedMemory)|
  +----------------------------------------------------------------------------+
  | Task              : This function is an interrupt routine .                |
  +----------------------------------------------------------------------------+
\*/

_VOID_ v_InterruptRoutine ( BYTE_ b_BoardHandle,
			    BYTE_ b_InterruptMask,
			    PUINT_ pui_ValueArray,
			    BYTE_ b_UserCallingMode,
			    VOID *pv_UserSharedMemory )
   {
   unsigned int ui_Cpt;
   unsigned int i_Index;
   unsigned short int *pusi_Index;


   str_UserStruct *ps_UserStruct = (str_UserStruct *) pv_UserSharedMemory;
   pusi_Index = pui_ValueArray;


   if ((b_InterruptMask&2) == 2)
   {
		/* EOS interrupt Acquisition */

		for (ui_Cpt= 0;ui_Cpt< pui_ValueArray [0];ui_Cpt++)
		   ps_UserStruct->ui_SaveArray [ps_UserStruct->b_ReceiveInterrupt] [ui_Cpt] = pui_ValueArray [ui_Cpt+1];


   }


   ps_UserStruct->b_ReceiveInterrupt ++;


   }




void main(void)
   {
   int i_Cpt;
   unsigned char b_Gain [4];
   unsigned char b_Polar [4];
   unsigned char b_Channel [4];
   unsigned char b_BoardHandle;
   int i_ReturnValue;

       /****************************/
       /* Print sample information */
       /****************************/

       printf ("\n\n");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n| xPCI-3001 SAMPLE24 :                                                  |");
       printf ("\n| Cyclic acquisition without using DMA with extern trigger.             |");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n| Connection suggested : Analog : ST010                                 |");
       printf ("\n|                                 PX 901 -AG or -A                      |");
       printf ("\n|                        Digital : FB 3000                              |");
       printf ("\n|                                  ST010                                |");
       printf ("\n|                                  PX 901 -ZG or -Z                     |");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n| Required connection :                                                 |");
       printf ("\n|     Set Pin 28 to -(0V)                                               |");
       printf ("\n|     Set Pin 20,21,22,23 to 10V.                                       |");
       printf ("\n|     Set the digital input 1 on 24V.                                   |");
       printf ("\n|     Then the value to read for each input is 4095.                    |");
       printf ("\n| Unipolar mode : 0V -> 0, 10V -> 4095                                  |");
       printf ("\n| Bipolar mode : -10V -> 0, 0V -> 2047, 10V -> 4095                     |");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n| <ESC> exit sample                                                     |");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n| Press any key for start the sample                                    |");
       printf ("\n+-----------------------------------------------------------------------+");
       printf ("\n\n");
       getch  ();
       flushall();

       i_ReturnValue = Initialisation (&b_BoardHandle);

       /*************************/
       /* Test the return value */
       /*************************/

       switch (i_ReturnValue)
	  {
	  case 0:
	       break;

	  case -1:
	       printf ("\nInitialisation error");
	       printf ("\nError = %d. ", i_ReturnValue);
	       break;
	  } // switch (i_ReturnValue)

       if(i_ReturnValue == 0)
	  {
	  i_ReturnValue = i_PCI3001_SetBoardIntRoutineWin32(b_BoardHandle,
							     PCI3001_SYNCHRONOUS_MODE,
							      sizeof (str_UserStruct),
							      (void **) &ps_GlobalUserStruct,
							     v_InterruptRoutine);


	  /*************************/
	  /* Test the return value */
	  /*************************/

	  switch (i_ReturnValue)
	     {
	     case 0:
		  printf ("\ni_PCI3001_SetBoardIntRoutineWin32 OK");
		  break;

	     case -1:
		  printf ("\ni_PCI3001_SetBoardIntRoutineWin32 error");
		  printf ("\nError = %d. The handle of the board is wrong", i_ReturnValue);
		  break;

	     case -2:
		  printf ("\ni_PCI3001_SetBoardIntRoutineWin32 error");
		  printf ("\nError = %d. Interrupt already installed", i_ReturnValue);
		  break;

	     default:
		  printf ("\ni_PCI3001_SetBoardIntRoutineWin32 error");
		  printf ("\nError = %d. ", i_ReturnValue);
		  break;
	     } // switch (i_ReturnValue)

	  if(i_ReturnValue == 0)
	     {

	     b_Channel[0] = PCI3001_CHANNEL_0;b_Gain[0] = PCI3001_1_GAIN;b_Polar[0] = PCI3001_UNIPOLAR;
	     b_Channel[1] = PCI3001_CHANNEL_1;b_Gain[1] = PCI3001_1_GAIN;b_Polar[1] = PCI3001_UNIPOLAR;
	     b_Channel[2] = PCI3001_CHANNEL_2;b_Gain[2] = PCI3001_1_GAIN;b_Polar[2] = PCI3001_UNIPOLAR;
	     b_Channel[3] = PCI3001_CHANNEL_3;b_Gain[3] = PCI3001_1_GAIN;b_Polar[3] = PCI3001_UNIPOLAR;

	     i_ReturnValue = i_PCI3001_InitAnalogInputAcquisition (b_BoardHandle,
								    4,
								    b_Channel,
								    b_Gain,
								    b_Polar,
								    PCI3001_SIMPLE_MODUS,
								    PCI3001_ENABLE,
								    1500,
								    0,
								    4,
								    PCI3001_DMA_NOT_USED,
								    PCI3001_SINGLE);
	     /*************************/
	     /* Test the return value */
	     /*************************/

	     switch (i_ReturnValue)
		{
		case 0:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition OK");
		     break;

		case -1:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. The handle of the board is wrong", i_ReturnValue);
		     break;

		case -2:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. User interrupt Routine has not been installed", i_ReturnValue);
		     break;

		case -3:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. Size of scan list is wrong", i_ReturnValue);
		     break;

		case -4:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. Wrong parameter detected in table pb_ChannelArray", i_ReturnValue);
		     break;

		case -5:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. Wrong parameter detected in table pb_GainArray", i_ReturnValue);
		     break;

		case -6:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. Wrong parameter detected in table pb_PolarityArray", i_ReturnValue);
		     break;

		case -7:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. Waiting time between two conversion cycles is too long", i_ReturnValue);
		     break;

		case -8:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. The selected time for ui_AcquisitionTiming or l_DelayTiming is wrong", i_ReturnValue);
		     break;

		case -9:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. Parameter b_DMAUsed is wrong", i_ReturnValue);
		     break;

		case -10:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. Parameter running time of the DMA conversion cycles is wrong ", i_ReturnValue);
		     printf ("\n (PCI3001_CONTINUOUS or PCI3001_SINGLE)");
		     break;

		case -11:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. Parameter conversion cycle is wrong (PCI3001_SIMPLE_MODUS or PCI3001_DELAY_MODUS)", i_ReturnValue);
		     break;

		case -12:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. Not enough memory available", i_ReturnValue);
		     break;

		case -13:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. Parameter b_ExternTrigger is wrong (PCI3001_ENABLE or PCI3001_DISABLE)", i_ReturnValue);
		     break;

		case -14:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. Parameter ul_NumberOfAcquisition is wrong", i_ReturnValue);
		     break;

		default:
		     printf ("\ni_PCI3001_InitAnalogInputAcquisition error");
		     printf ("\nError = %d. ", i_ReturnValue);
		     break;
		} // switch (i_ReturnValue)

	     if(i_ReturnValue == 0)
		{
		ps_GlobalUserStruct -> b_ReceiveInterrupt = 0;
		i_ReturnValue = i_PCI3001_StartAnalogInputAcquisition (b_BoardHandle);

		/*************************/
		/* Test the return value */
		/*************************/

		switch (i_ReturnValue)
		   {
		   case 0:
			printf ("\ni_PCI3001_StartAnalogInputAcquisition OK");
			break;

		   case -1:
			printf ("\ni_PCI3001_StartAnalogInputAcquisition error");
			printf ("\nError = %d. The handle of the board is wrong", i_ReturnValue);
			break;

		   case -2:
			printf ("\ni_PCI3001_StartAnalogInputAcquisition error");
			printf ("\nError = %d. Cyclyc acquisition has not benn initialised", i_ReturnValue);
			break;

		   case -3:
			printf ("\ni_PCI3001_StartAnalogInputAcquisition error");
			printf ("\nError = %d. User interrupt Routine has not been installed", i_ReturnValue);
			break;

		   default:
			printf ("\ni_PCI3001_StartAnalogInputAcquisition error");
			printf ("\nError = %d. ", i_ReturnValue);
			break;
		   } // switch (i_ReturnValue)

		if(i_ReturnValue == 0)
		   {
		   while ((ps_GlobalUserStruct->b_ReceiveInterrupt != 4) && (!kbhit()));
                   if (ps_GlobalUserStruct->b_ReceiveInterrupt != 4) 
                      printf ("\n No Interrupt occur ...");
                   else
                      {

		      printf("\n Acquisition 1 : %u %u %u %u ",ps_GlobalUserStruct->ui_SaveArray[0][0],
							    ps_GlobalUserStruct->ui_SaveArray[0][1],
							    ps_GlobalUserStruct->ui_SaveArray[0][2],
							    ps_GlobalUserStruct->ui_SaveArray[0][3]);
		      printf("\n Acquisition 2 : %u %u %u %u ",ps_GlobalUserStruct->ui_SaveArray[1][0],
							    ps_GlobalUserStruct->ui_SaveArray[1][1],
							    ps_GlobalUserStruct->ui_SaveArray[1][2],
							    ps_GlobalUserStruct->ui_SaveArray[1][3]);
		      printf("\n Acquisition 3 : %u %u %u %u ",ps_GlobalUserStruct->ui_SaveArray[2][0],
							    ps_GlobalUserStruct->ui_SaveArray[2][1],
							    ps_GlobalUserStruct->ui_SaveArray[2][2],
							    ps_GlobalUserStruct->ui_SaveArray[2][3]);
		      printf("\n Acquisition 4 : %u %u %u %u ",ps_GlobalUserStruct->ui_SaveArray[3][0],
							    ps_GlobalUserStruct->ui_SaveArray[3][1],
							    ps_GlobalUserStruct->ui_SaveArray[3][2],
							    ps_GlobalUserStruct->ui_SaveArray[3][3]);
                      }
		   i_ReturnValue = i_PCI3001_StopAnalogInputAcquisition(b_BoardHandle);

		   /*************************/
		   /* Test the return value */
		   /*************************/

		   switch (i_ReturnValue)
		      {
		      case 0:
			   printf ("\ni_PCI3001_StopAnalogInputAcquisition OK");
			   break;

		      case -1:
			   printf ("\ni_PCI3001_StopAnalogInputAcquisition error");
			   printf ("\nError = %d. The handle of the board is wrong", i_ReturnValue);
			   break;

		      case -2:
			   printf ("\ni_PCI3001_StopAnalogInputAcquisition error");
			   printf ("\nError = %d. Cyclyc acquisition has not benn started", i_ReturnValue);
			   break;

		      default:
			   printf ("\ni_PCI3001_StopAnalogInputAcquisition error");
			   printf ("\nError = %d. ", i_ReturnValue);
			   break;
		      } // switch (i_ReturnValue)

		   }
		i_ReturnValue = i_PCI3001_ClearAnalogInputAcquisition(b_BoardHandle);

		/*************************/
		/* Test the return value */
		/*************************/

		switch (i_ReturnValue)
		   {
		   case 0:
			printf ("\ni_PCI3001_ClearAnalogInputAcquisition OK");
			break;

		   case -1:
			printf ("\ni_PCI3001_ClearAnalogInputAcquisition error");
			printf ("\nError = %d. The handle of the board is wrong", i_ReturnValue);
			break;

		   case -2:
			printf ("\ni_PCI3001_ClearAnalogInputAcquisition error");
			printf ("\nError = %d. Cyclyc acquisition has not benn initialised", i_ReturnValue);
			break;

		   default:
			printf ("\ni_PCI3001_ClearAnalogInputAcquisition error");
			printf ("\nError = %d. ", i_ReturnValue);
			break;
		   } // switch (i_ReturnValue)

		}
	     i_ReturnValue = i_PCI3001_ResetBoardIntRoutine(b_BoardHandle);

	     /*************************/
	     /* Test the return value */
	     /*************************/

	     switch (i_ReturnValue)
		{
		case 0:
		     printf ("\ni_PCI3001_ResetBoardIntRoutine OK");
		     break;

		case -1:
		     printf ("\ni_PCI3001_ResetBoardIntRoutine error");
		     printf ("\nError = %d. The handle parameter of the board is wrong", i_ReturnValue);
		     break;

		case -2:
		     printf ("\ni_PCI3001_ResetBoardIntRoutine error");
		     printf ("\nError = %d. No Interrupt function initialised.", i_ReturnValue);
		     break;

		default:
		     printf ("\ni_PCI3001_ResetBoardIntRoutine error");
		     printf ("\nError = %d", i_ReturnValue);
		     break;
		} // switch (i_ReturnValue)

	     }
	  i_ReturnValue = i_PCI3001_CloseBoardHandle(b_BoardHandle);

	  /*************************/
	  /* Test the return value */
	  /*************************/

	  switch (i_ReturnValue)
	     {
	     case 0:
		  printf ("\ni_PCI3001_CloseBoardHandle OK");
		  break;

	     case -1:
		  printf ("\ni_PCI3001_CloseBoardHandle error");
		  printf ("\nError = %d. The handle parameter of the board is wrong", i_ReturnValue);
		  break;

	     default:
		  printf ("\ni_PCI3001_CloseBoardHandle error");
		  printf ("\nError = %d", i_ReturnValue);
		  break;
	     } // switch (i_ReturnValue)
	  }
       printf ("\n\n");
       printf ("\n+---------------------------------------------------+");
       printf ("\n| Program concluded.                                |");
       printf ("\n+---------------------------------------------------+");
       printf ("\n| Press ESC for exit from sample                    |");
       printf ("\n+---------------------------------------------------+");
       printf ("\n\n");

       /************/
       /* Wait ESC */
       /************/

       for (;;)
	  {
	  if (kbhit ())
	     {
	     if (getch () == 27)
		{
		break;
		} // if (getch () == 27);
	     } // if (kbhit ())
	  } // for (;;)

       printf ("\n\n");
   }

S
8.746 Beiträge seit 2005
vor 18 Jahren

Im Prinzip richtig, nur musst du "werte" nicht selbst mit GlobalHAlloc() allokieren. Du musst nur den IntPtr definieren und dann per "ref" übergeben. Die Routine allokiert den Speicher dann selbst (deswegen übergibst du vorher auch die Länge). Die Freigabe ist allerdings notwendig!

Ich verstehe es aber nicht wirklich, warum sie es so gemacht haben. Offenbar sind diese "wert" ja User-Daten. Sie werden nicht von der Routine gelesen oder geschrieben, trotzdem wird allokiert. Sehr merkwürdig.

M.E. macht es mehr Sinn (ohne Gewähr, weil ich nicht die Doku kenne), wenn du da nix übergibts (Länge 0 angeben) und direkt mit verwaltetem Speicher arbeitest. Im Prinzip dienen diese "werte" ja als Speicher zwischen der Interrupt-Routine und dem Rest des Codes. Da kannst du ja nehmen was du möchtest.

M
Masquerader Themenstarter:in
31 Beiträge seit 2005
vor 18 Jahren

Also, hab in der Doku grad nochmal nachgelesen. Der komische Pointer is in meinem Fall (auch im Falle des Beispiels) ohne Belang. Deswegen wird nix geschrieben bzw. gelesen.

Jetzt muss ich aber nochmal fragen:

  1. Wie krieg ich dort einen "Nulleintrag" hin, da eh nix gelesen und geschrieben wird?

  2. Wie mach ich das mit dem Zugriff auf meine Funktion v_InterruptRoutine?? Also Deklaration und dergleichen. Die Funktion soll nur i_ReceiveInterrupt = 1 setzen.

Wäre schön, wenn du das vielleicht als Code schreiben könntest. Bin grad ziemlich am verzweifeln und seh den Wald vor lauter Bäumen nicht mehr.....

Masque

S
8.746 Beiträge seit 2005
vor 18 Jahren
  1. Gib einfach "NULL" an.
  2. Nicht einfach den Namen der Funktion angeben sondern einen Delegaten erzeugen:


i_ReturnValue = i_PCI3001_SetBoardIntRoutineW32(
b_BoardHandle,                                                            PCI3001_ASYNCHRONOUS_MODE,
100,
pWerte,
new CallbackRoutine (v_InterruptRoutine));