2010-11-02 5 views
1

Notre interface composant COM a la méthode suivante:tlbimp.exe convertit HWND à _RemotableHandle

HRESULT CreatePluginWindow([in] HWND hParent, [in] RECT* prcView); 

Nous allons l'utiliser dans l'application .NET mais Interop pour cette interface est à la recherche comme ceci:

void CreatePluginWindow(ref interop.alfrontx._RemotableHandle hParent, ref interop.alfrontx.tagRECT prcView) 

Selon mon enquête, il n'y a aucun moyen d'utiliser cette méthode sans code dangereux. Je ne voudrais pas changer l'interface COM pour utiliser autre chose que le type HWND pour hParent, car il est utilisé dans de nombreux composants C++. Je ne voudrais pas faire de changement dans interop car ils sont compilés automatiquement sur chaque build.

Existe-t-il un autre moyen de résoudre ce problème?

Répondre

1

Ce n'est pas Tlbimp qui le fait, cela a été injecté par midl.exe lorsque vous avez construit le serveur COM non géré. Un handle de fenêtre est un obstacle d'interopérabilité car il s'agit d'une valeur 32 bits dans un programme 32 bits et d'une valeur 64 bits dans un programme 64 bits. Comme toutes les poignées.

Jetez un oeil au fichier wtypes.idl dans le répertoire Windows SDK include, vous y trouverez _RemotableHandle déclaré. Un peu plus loin, vous verrez le #define qui mappe le HWND à un RemotableHandle:

#ifndef _MIDL_DECLARE_WIREM_HANDLE 
DECLARE_WIREM_HANDLE(HWND); 
// etc.. 
#endif 

autant que je peux dire, quand vous passez le/D _MIDL_DECLARE_WIREM_HANDLE à midl.exe vous obtiendrez une bibliothèque de types sans le wrapper RemoteHandle. Certes, je ne comprends pas vraiment comment cela est censé fonctionner.

+1

Merci pour la solution! Après avoir ajouté le drapeau j'ai des erreurs de compilation, dans wtypes.idl et objidl.idl (ils utilisent HWND et HICON). Mais je les ai déclarés au début de l'idl et j'espère que l'interop contient IntPtr au lieu de _RemotableHandle. – Emendz

1

Je pense que vous pouvez convertir un IntPtr à un _RemotableHandle en utilisant le code suivant:

interop.alfrontx._RemotableHandle HWNDtoRemotableHandle(IntPtr handle) 
    { 
     return (interop.alfrontx._RemotableHandle)Marshal.PtrToStructure(handle, typeof(interop.alfrontx._RemotableHandle)); 
    } 

Ainsi, vous pouvez facilement utiliser la fonction ci-dessus pour obtenir le _RemotableHandle d'un IntPtr et il n'y a pas besoin de changer le type à l'intérieur de l'assembly .NET.