Avatar billede codecow Nybegynder
04. juli 2005 - 09:59 Der er 3 kommentarer og
1 løsning

COM og .NET interop: Class not registered

Hej.

Jeg forsøger at lave en .NET assembly som skal kunne benyttes via COM af en C++ klient.

SomeClass og SomeClassCollection fungerer fint, men Når jeg forsøger at få min server til at overfører disse som enten argumenter eller retur typer får jeg en "class not registered"
fejl når jeg prøver at skabe en instans af serveren.

Denne fejl er illustreret nedenstående. I den "rigtige" kode opstår der desuden "the system cannot find the file specified" og "Because of security restrictions, the type xxx.yyy cannot be accessed.", som jeg ikke kan replikerer her, men jeg forestiller mig at det skyldes "følgesygdomme" fra ovenstående problem.

Er der nogen som kan se hvad jeg gør forkert? Hvordan får jeg serveren til at modtage og returnere .NET klasser, og er der nogle design regler for at få .NET og COM interop til at spille lidt lettere?

Alt hjælp modtages med tak.

//------------------------------------------------------
using System;
using System.Collections;
using System.Runtime.InteropServices;

namespace TheNamespace {

    public enum SOME_ENUM { STATE1, STATE2, STATE3 }

    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ProgId("TheNamespace.SomeClass")]
    [Guid("CFEA397B-41AD-4dc4-8F5B-95E1ED0B5A62")]
    public class SomeClass {
       
        private int someVar;
       
        public SomeClass() {}
       
        public SomeClass( int i ) {
            this.SomeVar = i;   
        }
       
        public int foo() {
            return 42;
        }
       
        public int SomeVar {
            get { return someVar; }
            set { this.someVar = value; }
        }
           
        public void Show() {
            Console.WriteLine( "Value is:" + this.SomeVar );
        }   
    }
   
    [ComSourceInterfaces(typeof(_DEventInterface))]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ProgId("TheNamespace.SomeClassCollection")]
    [Guid("B84B24B7-5184-4256-A4B3-6172DB78E8CB")]
    public class SomeClassCollection : IEnumerable {
       
        [ComVisible(false)]
        public delegate void NotifyCallback( string str, SOME_ENUM e, int i );
        public /*static*/ event NotifyCallback NotifyEvent;
        private ArrayList theCollection = new ArrayList();

        public SomeClassCollection() {}

        public IEnumerator GetEnumerator() {
            return theCollection.GetEnumerator();
        }

        public void Add( SomeClass o ) {
            theCollection.Add( o );
            this.Notify();
        }
       
        public void RemoveAt( int i ) {
            theCollection.RemoveAt( i );
            this.Notify();
        }
       
        public void Clear() {
            theCollection.Clear();
            this.Notify();
        }

        public void TriggerEvent() {
            this.Notify();
        }

        private void Notify() {
            NotifyEvent( "event", SOME_ENUM.STATE3, 8 );
        }
    }

    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [Guid("A604AB66-E064-4363-8B2B-8433001C47E5")]
    public interface _DEventInterface {
        [DispId(1)] void NotifyEvent( string str, SOME_ENUM e, int i );
        [DispId(2)] void DebugEvent( string msg );
    }

    [ComSourceInterfaces(typeof(_DEventInterface))]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ProgId("TheNamespace.SomeService")]
    [Guid("3B2657B4-3850-4a3a-84A2-A893E316EBD6")]
    public class SomeService {
        private SomeClassCollection _theCol;
       
        public SomeService() {
            _theCol = new SomeClassCollection();
            _theCol.Add( new SomeClass( 3 ));   
            _theCol.Add( new SomeClass( 5 ));
            _theCol.Add( new SomeClass( 7 ));
            _theCol.Add( new SomeClass( 9 ));
        }

        public int foo() {
            return 42;
        }

        public SomeClassCollection GetSomeClassCollection() {
            return _theCol;
        }

        public SomeClass GetSomeClass() {
            SomeClass t = new SomeClass();
            foreach( SomeClass s in _theCol ) {
                t=s;
            }
            return t;
        }
    }
}


// Prøver her at bruge .NET klassen fra C++

    _SomeServicePtr pSvr( __uuidof( SomeService ));
    pSvr->GetSomeClassCollection();
Avatar billede lifo Nybegynder
04. juli 2005 - 10:48 #1
har ud brugt RegAsm.exe til at registrere din assambly
Avatar billede codecow Nybegynder
04. juli 2005 - 13:02 #2
Ja. Jeg har også givet den et strong name og lagt den ind i GAC. Desværer ikke med noget  held :(
Avatar billede codecow Nybegynder
04. juli 2005 - 15:26 #3
Det mærkelige er at hvis jeg ikke referer til mine egne klasser men kun til "almindelige typer" så funger det hele ok. Problemet ligger i interop delen.

F.eks.:

    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ProgId("TheNamespace.SomeService")]
    [Guid("3B2657B4-3850-4a3a-84A2-A893E316EBD6")]
    public class SomeService {

        public int foo() {
                        return 42;
        }
    }
Avatar billede codecow Nybegynder
06. juli 2005 - 14:00 #4
lukker
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester