2010-10-26 8 views
2

J'ai un contrôle ActiveX écrit en C# et fonctionne lorsqu'il est exécuté dans un programme compatible ActiveX (CoDeSys). Le problème que je suis venu à travers est que, afin de permettre CoDeSys d'interagir avec le contrôle ActiveX, CoDeSys nécessite la dll d'exporter le prototype de fonction:Définition de la fonction externe "C" en C#

void ExecuteActiveXCall(IUnknown* pUnk, char* pszId, char* pszParam, char* pszReturnBuffer, int nReturnBufferSize, DWORD* pdwReturnFlag); 

J'ai regardé sans succès sur la façon d'exporter cela comme vous pouvez en C++, comme le montre cet exemple:

extern "C" __declspec (dllexport) void ExecuteActiveXCall(IUnknown* pUnk, char* pszId, char* pszParam, char* pszReturnBuffer, int nReturnBufferSize, DWORD* pdwReturnFlag) 
{ 
    if (strcmp(pszId, "IWebBrowser|GoBack") == 0) 
    { 
    IUnknown* pNewUnk; 
    IWebBrowser* pwb; 
    pUnk->QueryInterface(IID_IWebBrowser, (void**) &pNewUnk); 
    pwb = (IWebBrowser*) pNewUnk; 

    if (pwb) 
    { 
     pwb->GoBack(); 
     pwb->Release(); 
    } 
    } 
    else if (strcmp(pszId, "IWebBrowser|GoForward") == 0) 
    { 
    IUnknown* pNewUnk; 
    IWebBrowser* pwb; 
    pUnk->QueryInterface(IID_IWebBrowser, (void**) &pNewUnk); 
    pwb = (IWebBrowser*) pNewUnk; 

    if (pwb) 
    { 
     pwb->GoForward(); 
     pwb->Release(); 
    } 
    } 
} 

C# ne un extern mot-clé, mais il ne vous permet pas de fournir la définition de la fonction (au moins je ne l'ai pas trouvé un moyen) . Après avoir essayé ceci:

extern unsafe void ExecuteActiveXCall(
     [MarshalAs(UnmanagedType.IUnknown)] object pUnk, 
     char* pszId, 
     char* pszParam, 
     char* pszReturnBuffer, 
     int nReturnBufferSize, 
     UInt32* pdwReturnFlag) 
    { 

    } 

L'erreur suivante se produit:

'AlarmsCSharp.AlarmsControl.ExecuteActiveXCall(object, char*, char*, char*, int, uint*)' cannot be extern and declare a body 

Quelqu'un at-il essayé exporter une fonction dans une dll C#?

Y a-t-il des solutions de contournement? (J'ai eu l'idée de [DllImport (« AlarmsCSharp.dll »)] et appeler C# dans le dll C++, mais je pensais voir si quelqu'un avait une solution avant)

Peut-être que je suis plus penser ce et n'ont pas besoin d'exporter cette fonction puisque le contrôle ActiveX est capable d'interagir déjà avec le code C#.

EDIT: J'ai une impression de ma traduction du prototype de la fonction C++ à la déclaration d'interface C#. Si quelqu'un ayant plus d'expérience avec la programmation C++/C# peut vérifier que j'ai fait cette traduction correcte ou incorrecte, cela peut être utile.

Répondre

0

Vous dites que CoDeSys est compatible avec ActiveX; avez-vous essayé d'utiliser COM interop?

+0

Je le crois. Voulez-vous faire référence à la case à cocher dans le projet ** Propriétés> Construire> S'inscrire à COM interop **? – blastthisinferno

0

Il semble y avoir 3 options principales; la première consiste à configurer COM interop où vous pouvez instancier votre contrôle/classe C# en utilisant COM. Je suis sûr que si vous faites des recherches, vous pouvez trouver plus d'informations à ce sujet.

La deuxième option est de rendre votre C++ module mixte géré/non géré, comme décrit ici: http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/5345a27a-a614-4a74-9f6d-ea7a999ddf83/

La troisième option consiste à utiliser "reverse PInvoke" comme décrit ici: http://tigerang.blogspot.com/2008/09/reverse-pinvoke.html

Il peut y avoir autres options; ce sont ceux que je connais.