P/Invoke - aber wie?? (Warnung CA1060)

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von praetor.

    P/Invoke - aber wie?? (Warnung CA1060)

    Hallo,
    in einem Modul haben ich folgenden Code, um eine INI-Datei zu schreiben und zu lesen:

    VB.NET-Quellcode

    1. Public Declare Ansi Function GetPrivateProfileString Lib "kernel32.dll" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Int32, ByVal lpFileName As String) As Integer
    2. Public Declare Ansi Function WritePrivateProfileString Lib "kernel32.dll" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpString As String, ByVal lpFileName As String) As Int32
    3. Public Function INI_WriteValueToFile(ByVal strSection As String, ByVal strKey As String, ByVal strValue As String, ByVal strFile As String) As Boolean
    4. 'Funktion zum Schreiben
    5. 'strSection = Sektion in der INI-Datei
    6. 'strKey = Name des Schlüssels
    7. 'strValue = Wert, der geschrieben werden soll
    8. 'strFile = Vollständiger Pfad zur INI-Datei
    9. Return (Not (WritePrivateProfileString(strSection, strKey, strValue, strFile) = 0))
    10. End Function
    11. Public Function INI_ReadValueFromFile(ByVal strSection As String, ByVal strKey As String, ByVal strDefault As String, ByVal strFile As String) As String
    12. 'Funktion zum Lesen
    13. 'strSection = Sektion in der INI-Datei
    14. 'strKey = Name des Schlüssels
    15. 'strDefault = Standardwert, wird zurückgegeben, wenn der Wert in der INI-Datei nicht gefunden wurde
    16. 'strFile = Vollständiger Pfad zur INI-Datei
    17. Dim strTemp As String = Space(1024), lLength As Integer
    18. lLength = GetPrivateProfileString(strSection, strKey, strDefault, strTemp, strTemp.Length, strFile)
    19. Return (strTemp.Substring(0, lLength))
    20. End Function


    Zu den Zeile 1 und 3 kommt bei der Codeanalyse:
    "Warnung CA1060 Als P/Invoke-Methode muss 'Module1.GetPrivateProfileString(ByRef String, ByRef String, ByRef String, ByRef String, Integer, ByRef String)' in einer Klasse mit dem Namen NativeMethods, SafeNativeMethods oder UnsafeNativeMethods definiert werden."

    Mir ist schon klar, dass es sich bei den beiden Deklarationen um ungemanagten Code handelt und ich habe dazu hier und hier nachgelesen.
    Leider komme ich trotzdem nicht dahinter, wie der Code korrekt modifiziert werden muss, damit die Warnung unterbleibt.
    Kann wer helfen?
    Grüße
    praetor

    praetor schrieb:

    Codeanalyse
    Lege eine Klasse mit dem Namen NativeMethods an und pack die Deklarationen und Konstanten, Strukturen usw. dort rein.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Lege eine Klasse mit dem Namen <code class="inlineCode">NativeMethods</code> an und pack die Deklarationen und Konstanten, Strukturen usw. dort rein.

    Mmh, will nicht so recht. Das

    VB.NET-Quellcode

    1. Public Class NativeMethods
    2. Public Declare Ansi Function GetPrivateProfileString Lib "kernel32.dll" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Int32, ByVal lpFileName As String) As Integer
    3. Public Declare Ansi Function WritePrivateProfileString Lib "kernel32.dll" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpString As String, ByVal lpFileName As String) As Int32
    4. End Class

    führt zu:
    "Fehler BC30451 "WritePrivateProfileString" wurde nicht deklariert. Aufgrund der Schutzstufe ist unter Umständen kein Zugriff möglich."

    Wenn ich die Funktionsdefinitionen mit in die Klasse packe, wird es auch nicht besser. Ich hab auch versucht, die Klasse nicht in dem Modul anzulegen, sondern als separate Klasse - wird auch nicht besser.
    Ich brauch bitte etwas konkretere Hilfe.
    Grüße
    praetor

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „praetor“ ()

    Hm. Ich kann's gerade nicht nachvollziehen. Hab ne Friend Class NativeMethods und darin Deine VB6-Funktionsdeklarationen. In VS2019Pre mit allen Codeanalyseregeln geht alles i.O.

    btw: Auf pinvoke.net gibt's ne zeitgemäßere Deklaration.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    praetor schrieb:

    WritePrivateProfileString
    :rolleyes:
    Wenn Du die Deklarationen in einer andern Klasse hast, musst Du auch über die zugreifen:

    VB.NET-Quellcode

    1. NativeMethods.GetPrivateProfileString(...)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke an alle :thumbup: , die Behandlung der INI-Datei funktioniert jetzt soweit. Hab zwischenzeitlich auch Einbindung einer fertigen DLL versucht, das aber dann doch wieder verworfen. Ich bekomme jetzt noch die Warnung:

    "Warnung CA1401 Ändern Sie den Zugriff auf P/Invoke 'NativeMethods.GetPrivateProfileString(ByRef String, ByRef String, ByRef String, ByRef String, Integer, ByRef String)' so, dass die Methode außerhalb der Assembly nicht mehr sichtbar ist."

    Ein paar Versuche, dass noch gerade zu biegen, sind gescheitert. Aber das ist vielleicht verschmerzbar? Die Klasse sieht jetzt so aus:

    VB.NET-Quellcode

    1. Public Class NativeMethods
    2. ' INI schreiben / lesen
    3. Public Declare Ansi Function GetPrivateProfileString Lib "kernel32.dll" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Int32, ByVal lpFileName As String) As Integer
    4. Public Declare Ansi Function WritePrivateProfileString Lib "kernel32.dll" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpString As String, ByVal lpFileName As String) As Int32
    5. Public Function INI_WriteValueToFile(ByVal strSection As String, ByVal strKey As String, ByVal strValue As String, ByVal strFile As String) As Boolean
    6. 'Funktion zum Schreiben
    7. 'strSection = Sektion in der INI-Datei
    8. 'strKey = Name des Schlüssels
    9. 'strValue = Wert, der geschrieben werden soll
    10. 'strFile = Vollständiger Pfad zur INI-Datei
    11. Return (Not (WritePrivateProfileString(strSection, strKey, strValue, strFile) = 0))
    12. End Function
    13. Public Function INI_ReadValueFromFile(ByVal strSection As String, ByVal strKey As String, ByVal strDefault As String, ByVal strFile As String) As String
    14. 'Funktion zum Lesen
    15. 'strSection = Sektion in der INI-Datei
    16. 'strKey = Name des Schlüssels
    17. 'strDefault = Standardwert, wird zurückgegeben, wenn der Wert in der INI-Datei nicht gefunden wurde
    18. 'strFile = Vollständiger Pfad zur INI-Datei
    19. Dim strTemp As String = Space(1024), lLength As Integer
    20. lLength = GetPrivateProfileString(strSection, strKey, strDefault, strTemp, strTemp.Length, strFile)
    21. Return (strTemp.Substring(0, lLength))
    22. End Function
    23. End Class

    und ich instanziere wie folgt:

    VB.NET-Quellcode

    1. ​Public NativeMethods As New NativeMethods

    An verschiedenen Stellen Von Public zu Privat zu wechseln, hat irgendwie nichts gebracht.
    Grüße
    praetor

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „praetor“ ()

    siehe Post#4: deklariere die Klasse nicht mit Public, sondern mit Friend. Dann ist sie in Deinem Projekt überall zugänglich. Aber wenn Dein Projekt in einem anderen eingebunden wird, ist die Klasse dort unsichtbar. Und die Warnung verschwindet.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @praetor Manchmal hilft es, Frau Google die Nummer der Warnung einzugeben:

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!