Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

VB Deklaration von Strukturen aus Header und C-dll-Funktion

Empfohlene Antworten

Veröffentlicht

Hallo Leute,

ich habe ein Problem, mit der Deklaration von Strukturen in VB - und der Dek. einer C-dll.

Hier der Code aus der Header-Datei.

typedef struct tagDM_VARKEYA

{

    DWORD       dwKeyType;                                   

    DWORD       dwID;                                      

    char        szName[ MAX_DM_VAR_NAME + 1 ];                               

    LPVOID      lpvUserData;                                 

} DM_VARKEYA, FAR *LPDM_VARKEYA;

#if....

DM_VARKEY = DM_VARKEYA;

...

...

In VB steht dann dieses hier:
<StructLayout(LayoutKind.Sequential, Pack:=1)>

Public Structure DM_VARKEY

    Public dwKeyType As UInt32

    Public dwID As UInt32

    Public szName() As Char

    Public lpvUserData As IntPtr

End Structure
Und hier habe ich schon das erste Problem: Wie kann ich den szName auf 128 Byte setzen. Ein

Dim vKey as DM_VARKEY

Marshal.SizeOf(vKey)
sagt, dass die Struktur nur 12 Byte groß ist. 2 x DWORD (4 Byte) + 1 x IntPtr (4 Byte) = 12.. wo ist szName? Nun zur DLL. in der API_Doku steht dies hier:
BOOL DMGetValue (LPDM_VARKEY lpdmVarKey, DWORD dwItems, LPDM_VAR_UPDATE_STRUCT lpdmvus, LPCMN_ERROR lpdmError);

Unter C würde dies so aussehen.

CMN_ERROR err;

DM_VARKEY vKey;

DM_VAR_UPDATE_STRUCT update;

DWORD items = 1;


ZeroMemory(&vKey, sizeof(vKey));

ZeroMemory(&err, sizeof(err));


vKey.dwKeyType = DM_VARKEY_NAME; //DM_VARKEY_NAME = 2

strcpy(varKey.szName,"TESTVAR");

varKey.lpvUserData = NULL;


DMGetValue( &vKey, items, &update, &err ); //funktioniert super!

Wie muss die Funktion nun aber in VB deklariert werden? Ich habe es so gemacht, nur leider funktioniert das nicht.

Declare Ansi Function DM_GetValue Lib "dmclient.dll" Alias "DMGetValueA" _

        (ByVal lpdmVarKey As IntPtr, _

         ByRef dwItems As UInt32, _

         ByVal lpdmvus As IntPtr, _

         ByVal lpdmError As IntPtr) As Boolean

Ich hoffe, das Ihr mir da helfen könnt. Steh völlig auf dem Schlauch.

vG

Hi NancyG,

ich habe ein Problem, mit der Deklaration von Strukturen in VB - und der Dek. einer C-dll.

Hier der Code aus der Header-Datei.

Das Zauberwort: Marshal. Wenn ich den Code so sehe - Siemens lässt grüßen!

Was du machen willst ist: managed mit unmanaged code. Beim .Net ist es so, dass sich Net um den Speicher kümmert, alloziert, freigibt usw... Diese Mechanismen gilt es für diesen Anwendungsfall auszuschalten.

Ein Stück davon hast du schon drin:

<StructLayout(LayoutKind.Sequential, Pack:=1)>
.
typedef struct tagDM_VARKEYA

{

    DWORD       dwKeyType;                                   

    DWORD       dwID;                                      

    char        szName[ MAX_DM_VAR_NAME + 1 ];                               

    LPVOID      lpvUserData;                                 

} DM_VARKEYA, FAR *LPDM_VARKEYA;

[/QUOTE]


Sollte so funktionieren:

[CODE]

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=1)> _

Public Class DM_VARKEY

    <MarshalAs(UnmanagedType.U4)> _

    Public dwKeyType As DM_VARKEY_TYPE

    <MarshalAs(UnmanagedType.U4)>

    Public dwID As UInt32

    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=(MAX_DM_VAR_NAME + 1))>

    Public szName As [String]

    Public lpvUserData As IntPtr

End Class

Es fehlt noch die Err_Struct :) :

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=1)>

Public Class CMN_ERROR

    <MarshalAs(UnmanagedType.U4)>

    Public dwError1 As UInt32

    Public dwError2 As UInt32

    Public dwError3 As UInt32

    Public dwError4 As UInt32

    Public dwError5 As UInt32


    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=512)>

    Public szErrorText As [String]


    Sub reset()

        dwError1 = 0

        dwError2 = 0

        dwError3 = 0

        dwError4 = 0

        dwError5 = 0

        szErrorText = ""

    End Sub


End Class

Mit [reset()] kannst du das Objekt schnell wieder leeren. Und hier die DLL:

<DllImport("dmclient.dll", EntryPoint:="DMGetValueA", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _

Private Shared Function DMGetValue(<[In]()> <MarshalAs(UnmanagedType.LPStruct)> ByVal lpdmVarKey As DM_VARKEY, _

                                   <[In]()> ByVal dwItems As UInt32, _

                                   <[In]()> ByVal lpdmvus As IntPtr, _

                                   <[In](), Out()> ByRef lpdmError As CMN_ERROR

                                  ) As Boolean

Ich würde dir aber die DMGetValueWait empfehlen. Bei dieser werden die Daten, sofern sie keine Internen Variablen sind, aus der SPS gelesen/synchronisiert. Die (WAIT) erwartet aber eine CallBack-Funktion, die du über DELEGATE realisieren kannst.

Du solltest darauf achten, dass du überall das gleiche CharSet benutzt. Ich empfehle CharSet.Ansi

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.