2009-05-30 10 views
2

Le cas:utilisant le code non managé dans .NET

Il y a une application .NET appelant code non managé C. Méthode utilisée pour ceci:

public static class MiracleCreator 
{ 
    [DllImport("Library.dll")] 
    private static extern void RunUnmanaged(string fileName); 

    public static void Run(string fileName) 
    { 
     RunUnmanaged(fileName); 
    } 
} 

Il est utilisé dans une application Windows Forms et le nom de fichier nécessaire est obtenu par OpenFileDialog. Code:

if (openFileDialog.ShowDialog() == DialogResult.OK) 
{ 
    MiracleCreator.Run(openFileDialog.FileName); 
} 

Le problème:

Après plusieurs exécutions du code dans l'application Windows Forms le OpenFileDialog se casse à l'exception:. « Tentative de lecture ou d'écriture mémoire protégée Ceci est souvent une indication que l'autre mémoire est corrompue. "

Dans la recherche de solution:

Essayer "plus fiable" utilisation de OpenFileDialog ne vous aide pas. Comme cette solution (a essayé de donner le lien, mais "les nouveaux utilisateurs ne sont pas autorisés à ajouter des liens hypertextes" :)):

public class Invoker 
{ 
    public OpenFileDialog InvokeDialog; 
    private Thread InvokeThread; 
    private DialogResult InvokeResult; 

    public Invoker() 
    { 
     InvokeDialog = new OpenFileDialog(); 
     InvokeThread = new Thread(new ThreadStart(InvokeMethod)); 
     InvokeThread.SetApartmentState(ApartmentState.STA); 
     InvokeResult = DialogResult.None; 
    } 

    public DialogResult Invoke() 
    { 
     InvokeThread.Start(); 
     InvokeThread.Join(); 
     return InvokeResult; 
    } 

    private void InvokeMethod() 
    { 
     InvokeResult = InvokeDialog.ShowDialog(); 
    } 
} 

Utilisation:

 Invoker I = new Invoker(); 

     if (I.Invoke() == DialogResult.OK) 
     { 
      MessageBox.Show(I.InvokeDialog.FileName, "Test Successful."); 
     } 
     else 
     { 
      MessageBox.Show("Test Failed."); 
     } 

Questions:

est le exception vraiment causée par le code non managé? D'autres problèmes pourraient-ils être attendus (rupture de quelque chose de différent de OpenFileDialog)? Quelle est la meilleure approche pour cela?

Merci pour chaque idée/solution.

Répondre

1

Vous devez spécifier l'attribut MarshalAs approprié pour le paramètre string de la déclaration de méthode. Quelque chose comme:

[DllImport("Library.dll")] 
private static extern void RunUnmanaged(
    [MarshalAs(UnmanagedType. ...)] string fileName); 
+0

... Eh bien essayer de suivre vos conseils, mais il est difficile de « deviner » tous les attributs nécessaires ... :) La vraie méthode importée ressemble: [DllImport (« Library.dll »)] private static extern int Exécuter (string [] fileLines, int lignesCount, chaîne filePath, int someIntValue, ref chaîne errorMsg, ref int refIntValue, ref chaîne refStringValue); Essayé d'utiliser UnmanagedType.LPArray pour string [] et UnmanagedType.LPStr pour chaîne et ref chaîne. Rien n'a empiré et rien ne s'est amélioré :). S'il vous plaît aider avec les attributs corrects. – Alex

+0

@Alex: Affichez la signature non gérée –

+0

Comme l'a dit Mehrdad, la signature aiderait. Enveloppez-vous autre chose, comme un rappel ou un autre appel de fonction? –

0

Même en utilisant errror SaveFileDialog via le code managé dans une application .NET Windows Forms (fonctionnant sous Windows 7 32 bits) que l'exposition de la saveAs d'un formulaire modal avec des données chargées à partir d'un db. Après des heures de débogage laids et essais/erreurs, mes yeux sont tombés sur une propriété, je ne savais pas qu'il y avait avant: en VB.NET, je l'ai écrit

Dim sfv As New System.Windows.Forms.SaveFileDialog 
    With sfv 
    .AutoUpgradeEnabled = False 
    '[...] 

et l'erreur a disparu.

Questions connexes