2009-11-10 17 views
0

je convertir une fonction de Visual Basic 6.0 comme:La conversion d'une fonction à partir de Visual Basic 6.0 à C# est de lancer AccessViolationException

Declare Function RequestOperation Lib "archivedll" (ByVal dth As Long, ByVal searchRequestBuf As String, ByVal buflen As Long, ByVal FieldNum As Long, ByVal OP As Long, ByVal value As String) As Long 

En C#, je suis déclarer la fonction comme:

[DllImport("archivedll")] 
public static extern int RequestOperation(int dth ,StringBuilder searchRequestBuf, int bufferLen, int fieldNum, int op, string value); 

lorsque l'appel RequestOperation de C#, il jette une exception:

[System.AccessViolationException] = {"Tentative de lecture ou d'écriture de la mémoire protégée . Ceci est souvent une indication qu'une autre mémoire est corrompu. "}

J'ai réussi à appeler beaucoup d'autres fonctions comme celle-ci, mais seulement cette fonction génère l'exception.

Répondre

3

Cette fonction est clairement pas lancer une AccessViolationException -.. à la place, il génère une erreur de violation d'accès par « tentative de lecture ou d'écriture de mémoire protégée » .NET est traduisez cette faute dans un AccessViolationException

Vous devez aller comprendre pourquoi il est « tentative de lire ou écrire de la mémoire protégée. "En particulier, avez-vous initialisé le StringBuilder vous y passez? Veuillez poster le code que vous utilisez pour appeler cette méthode.

+0

Oui j'initialiser le StringBuilder avec capicity = 4096 code VB6 appeler Dim bufSearchRequest As String * 4096 RETCODE = SearchRequestOperation (hDocumentType, bufSearchRequest, Len (bufSearchRequest), fieldIdx, querytype, stringQuery) et ce est l'appel C# StringBuilder searchRequest = new StringBuilder (4096); retCode = RequestOperation (hDocumentType, searchRequest, searchRequest.Capacity, index, type de requête, requête); –

+0

Comme le dit Eran, l'erreur se produit clairement parce que vous passez un objet StringBuilder dans une fonction qui attend une chaîne. Ils ne sont pas interchangeables. –

+0

Eran est incorrect. La DLL renvoie une chaîne via l'argument searchRequestBuf. Par conséquent, StringBuilder doit être utilisé. La chaîne ne peut être utilisée que si la DLL ne modifie pas la chaîne d'entrée. Voir par exemple ici. http://msdn.microsoft.com/en-us/library/ms235282(VS.80).aspx – MarkJ

0

Je pense que le StringBuilder dans la déclaration de fonction a quelque chose à voir avec cela. Vous devriez utiliser simplement String à la place.

+0

Le type de paramètre StringBuilder est utilisé pour [OutAttribute] –

+1

Je ne pense pas que ce soit important. Néanmoins, vous n'avez aucune raison d'utiliser StringBuilder en tant que paramètre car il suppose de ** construire des chaînes ** dans une performance optimisée et de ne pas passer en tant que conteneur de données. –

+1

-1 Eran, vous avez tort.La DLL renvoie une chaîne via l'argument searchRequestBuf. Par conséquent StringBuilder doit être utilisé - String ne peut pas être utilisé car les chaînes .NET sont immuables. Voir par exemple ici sur MSDN http://msdn.microsoft.com/en-us/library/ms235282(VS.80).aspx – MarkJ

0
/// Return Type: int 
///dth: int 
///searchRequestBuf: BSTR->OLECHAR* 
///buflen: int 
///FieldNum: int 
///OP: int 
///value: BSTR->OLECHAR* 
[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="RequestOperation")] 

extern statique public int RequestOperation (int dth, [System.Runtime.InteropServices.MarshalAsAttribute (System.Runtime.InteropServices.UnmanagedType.BStr)] string searchRequestBuf, int buflen, int numChamp, int OP, [System .Runtime.InteropServices.MarshalAsAttribute (System.Runtime.InteropServices.UnmanagedType.BStr)] valeur de chaîne);

+0

Dans une instruction VB6 'Declare', une chaîne ByVal est placée en tant que pointeur sur une chaîne ANSI et non sur un BSTR. Si vous voulez l'écrire ainsi, cela devrait être 'System.Runtime.InteropServices.UnmanagedType.LPStr' fois – MarkJ