Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    [VB.NET] Utilizzo di una DLL (creata in C)

    Salve a tutti!

    Sto provando a creare un'applicazione in VB.net, e per fare ciò dovrei usare dei metodi della libreria GRF.dll (il GRF è un tipo di archivio, come dire RAR o ZIP, ma sviluppato da una singola azienda); il sorgente di questa libreria, con la relativa documentazione, è disponibile qui:
    http://openkore.sourceforge.net/grftool/html

    Quindi in Visual Basic, leggendo le varie dichiarazioni, ho inserito questo codice:
    codice:
    ' GRF Types
        Enum GrfErrorType
            GE_SUCCESS
            GE_BADARGS
            GE_INVALID
            GE_CORRUPTED
            GE_NSUP
            GE_NOTFOUND
            GE_INDEX
            GE_ERRNO
            GE_ZLIB
            GE_ZLIBFILE
            GE_NODATA
            GE_BADMODE
            GE_NOTIMPLEMENTED
        End Enum
    
        Public Structure GrfError
            Dim type As GrfErrorType
            Dim line As Integer
            Dim name As String
            Dim func As String
            Dim extra As Int64
        End Structure
    
        Public Structure GrfFile
            Dim compressed_len_aligned As Integer
            Dim compressed_len As Integer
            Dim real_len As Integer
            Dim flags As Int16
            Dim hash As Integer
            Dim name As String
            Dim data As String
        End Structure
    
        Public Structure Grf
            Dim filename As String
            Dim len As Integer
            Dim type As Integer
            Dim version As Integer
            Dim nfiles As Integer
            Dim files() As GrfFile
            Dim first As GrfFile
            Dim last As GrfFile
    
            Dim allowCrypt As Int16
            Dim f As System.IO.File
            Dim allowWrite As Int16
            Dim zbuf As Object ' void
        End Structure
    
        Public Structure GrfOpenCallback
            Dim file As GrfFile
            Dim mError As GrfError
        End Structure
    
        ' GRF Library (grf.dll) functions
        Public Declare Function GrfOpen Lib "grf.dll" Alias "grf_open" (ByVal fname As String, ByVal mode As String, ByVal mError As GrfError, ByVal callback As GrfOpenCallback) As Grf
        Public Declare Function GrfExtract Lib "grf.dll" Alias "grf_extract" (ByVal grf As Grf, ByVal grfname As String, ByVal file As String, ByVal mError As GrfError) As Integer
        Public Declare Function GrfClose Lib "grf.dll" Alias "grf_close" (ByVal grf As Grf)
        Public Declare Function GrfFree Lib "grf.dll" Alias "grf_free" (ByVal grf As Grf)
    inoltre ho utilizzato una Sub per l'utilizzo di queste

    codice:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim myGrf As Grf
            Dim err1 As GrfError
            Dim grf1 As GrfOpenCallback
            myGrf = GrfOpen("archivio.grf", "rb", err1, grf1)
        End Sub
    Ovviamente all'avvio non funziona e mi restituisce questo errore:

    MarshalDirectiveException non è stata gestita.
    La firma del tipo del metodo non è compatibile con PInvoke.
    e nella finestra di controllo imeddiati restituisce:
    Eccezione first-chance di tipo 'System.Runtime.InteropServices.MarshalDirectiveEx ception' in GrfManager.exe
    Ovviamente se aggiungo la libreria come riferimento da errore (me lo immaginavo poiche non c'entra nulla col .NET)

    E' colpa della libreria troppo vecchia? o il fatto che è in C? o delle dichiarazioni?
    Qualsiasi aiuto/commento è ben gradito

    Grazie in anticipo!
    ..:: Portfolio in costruzione ::..
    ..:: http://rlj.abshost.net ::..

  2. #2
    GrfOpenCallback non è una struttura ma un puntatore a funzione. In VB.NET devi scriverlo come un delegato; la definizione della struttura è in molti punti errata, come evidenziato di seguito:
    codice:
    Public Structure Grf
            Dim filename As String
            Dim len As Integer
            Dim type As Integer
            Dim version As Integer
            Dim nfiles As Integer
            Dim files() As GrfFile 'Su questo non sarei così sicuro...
            Dim first As GrfFile 'Questo (e quello che segue) è un PUNTATORE a GrfFile, non una struttura GrfFile
            Dim last As GrfFile
    
            Dim allowCrypt As Int16 'Questo dovrebbe essere un intero a 8 bit senza segno; questo tipo di dati non esiste in .NET
            Dim f As System.IO.File 'Non puoi usare uno stream .NET al posto di un puntatore a FILE!
            Dim allowWrite As Int16 'Vale lo stesso discorso fatto per allowCrypt
            Dim zbuf As Object 'Come già detto dovrebbe essere un IntPtr
        End Structure
    .
    Inoltre la funzione non restituisce una struttura Grf, ma un puntatore ad essa.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Infatti, ammetto di non capire minimamente come convertire da C a VB =)
    Come posso creare un puntatore in VB?
    scusami ancora ma sono di mente antica.. rimasto a VB6, di minimo :P

    E inoltre come posso fare un puntatore a una funzione?

    Editps, non avevo letto IntPtr grazie =D
    però non ho ben capito l'utilizzo... cerco qualcosa e al massimo edito

    Grazie per la pazienza!
    ..:: Portfolio in costruzione ::..
    ..:: http://rlj.abshost.net ::..

  4. #4
    Originariamente inviato da Rocklion
    Infatti, ammetto di non capire minimamente come convertire da C a VB =)
    Non è solo una tua colpa, molte caratteristiche del C non sono disponibili in VB.NET.
    Come posso creare un puntatore in VB?
    Non puoi, o almeno, non esplicitamente; se si trattasse di un argomento potresti semplicemente passare la struttura ByRef, ma per un valore di ritorno di una funzione o per il contenuto di una struttura non saprei neanch'io cosa fare... forse usando IntPtr o qualche attributo per cambiare il marshalling che attua PInvoke... ma si tratta di tecniche piuttosto ingarbugliate (al massimo dò un'occhiata sui miei testi sacri e ti faccio sapere). Comunque credo che converrebbe scrivere una dll wrapper in C/C++ che, esportando funzioni più ".NET friendly" chiami le funzioni della dll in questione.
    E inoltre come posso fare un puntatore a una funzione?
    Anche qui, il .NET Framework non supporta direttamente i puntatori a funzione, ma permette di usare i delegate per questo scopo. Comunque ho visto nella documentazione che se non ti serve specificare una funzione di callback puoi passare a quel parametro NULL, per cui ti basta dichiararlo come IntPtr e passarci IntPtr.Zero.
    codice:
    Public Declare Function GrfOpen Lib "grf.dll" Alias "grf_open_callback" (ByVal fname As String, ByVal mode As String, ByVal mError As GrfError, ByVal callback As IntPtr) As Grf
    Nota che comunque questa dichiarazione è errata, visto che il valore di ritorno dovrebbe essere un puntatore.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Grazie mille per la spiegazione! , semplice ed efficace ^^

    Provo subito ad applicare queste modifiche, se non funziona (cosa molto probabile) beh, non è un problema, vedrò di ripassarmi un pò il C++ :P

    Grazie ancora, ciao!
    ..:: Portfolio in costruzione ::..
    ..:: http://rlj.abshost.net ::..

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.