Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi C#.Net2.0 DLL in Delphi2007 nutzen (Com)? (https://www.delphipraxis.net/108415-c-net2-0-dll-delphi2007-nutzen-com.html)

winx 13. Feb 2008 09:30


C#.Net2.0 DLL in Delphi2007 nutzen (Com)?
 
Hallo,

habe eine Assembly die ich nun unter Delphi nutzen möchte.

Ich habe die Klassen wie folgt aufgebaut:

Code:
    [ComVisible(true)]
    public class DotNetClass
    {
        /// <summary>
        /// Der Int Wert der Klasse
        /// </summary>
        private int m_ValueInt = 0;

        /// <summary>
        /// Der String der Klasse
        /// </summary>
        private readonly string m_ValueString = String.Empty;

        /// <summary>
        /// Das utilitiy Objekt
        /// </summary>
        private Utility m_Util = new Utility();

       
        /// <summary>
        /// Standardkonstruktor
        /// </summary>
        public DotNetClass()
        {
            m_ValueString = "Hallo";
            m_ValueInt = 7;
            m_Util = new Utility();

        }
...

Die AssmeblyInfo.cs sieht so aus:
Code:
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DotNetDLL")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("NWL Lasertechnologie ")]
[assembly: AssemblyProduct("DotNetDLL")]
[assembly: AssemblyCopyright("Copyright © NWL Lasertechnologie 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(true)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("fc0e9806-4758-482d-b677-d11598f1cd3c")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Nun möchte ich das gerne in Delphi einbinden und das klappt auch.

Nur sehe ich nur die Klassen, aber keine Properties und Funktionen...

Wo liegt noch mein Fehler?

Danke,
winx

Bernhard Geyer 13. Feb 2008 09:42

Re: C#.Net2.0 DLL in Delphi2007 nutzen (Com)?
 
Wenns du bei allen Properties und Methoden die Sichtbarkeit mittels private beschrängst ist das kein Wunder ...

winx 13. Feb 2008 09:46

Re: C#.Net2.0 DLL in Delphi2007 nutzen (Com)?
 
Das ist nur ein Ausschnitt aus der Klasse, die komplette ist hier:

Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace DotNetDLL
{
    [ComVisible(true)]
    public class DotNetClass
    {
        /// <summary>
        /// Der Int Wert der Klasse
        /// </summary>
        private int m_ValueInt = 0;

        /// <summary>
        /// Der String der Klasse
        /// </summary>
        private readonly string m_ValueString = String.Empty;

        /// <summary>
        /// Das utilitiy Objekt
        /// </summary>
        private Utility m_Util = new Utility();

       
        /// <summary>
        /// Standardkonstruktor
        /// </summary>
        public DotNetClass()
        {
            m_ValueString = "Hallo";
            m_ValueInt = 7;
            m_Util = new Utility();

        }


        /// <summary>
        /// Konstuktor 2
        /// </summary>
        /// <param name="m_ValueInt">Zahl</param>
        /// <param name="m_ValueString">String</param>
        /// <param name="m_Util">Objekt</param>
        public DotNetClass(int m_ValueInt, string m_ValueString, Utility m_Util)
        {
            this.m_ValueInt = m_ValueInt;
            this.m_ValueString = m_ValueString;
            this.m_Util = m_Util;
        }



        /// <summary>
        /// Der Int Wert der Klasse
        /// </summary>
        public int ValueInt
        {
            get { return m_ValueInt; }
            set { m_ValueInt = value; }
        }


        /// <summary>
        /// Der String der Klasse
        /// </summary>
        public string ValueString
        {
            get { return m_ValueString; }
        }


        public int add(int a,int b)
        {
            return a + b;
        }
    }
}
also daran kanns nicht liegen

Elvis 13. Feb 2008 10:12

Re: C#.Net2.0 DLL in Delphi2007 nutzen (Com)?
 
Zitat:

Zitat von winx
Wo liegt noch mein Fehler?

Erstmal ist ein Fehler, dass wir deine Eigenschaften und Methoden von "Utility" nicht sehen können, somit können wir dir unmöglich sagen, ob die COM-compatibel sind.

Zitat:

Nun möchte ich das gerne in Delphi einbinden und das klappt auch.
Nur sehe ich nur die Klassen, aber keine Properties und Funktionen...
Per default veröffentlicht .Net Klassen zu COM nur als IDispatch.
Das heißt, du schreibst die Methoden und Properties einfach so in den Delphi-Code, und hoffst dass sie richtig geschrieben sind. :angle2:
Falls Namen und Parameter stimmen, dann werden die richtigen Methoden in den .Net Klassen ausgeführt.
Natürlich ist das furchtbar, aber Late-binding ist immer furchtbar. :kotz:

Um eine richtige COM-Typelib aus deiner Assembly generieren zu können, musst du für alle zu exportierenden Klassen ein Interface anlegen.
Dieses Interface braucht dann noch eine GUID, und du musst ihm sagen, dass es auch wirklich Early Binding unterstützen soll.
Am besten ist hier "InterfaceIsDual", da du sowohl Early Binding hast, als auch Late Binding für die ganzen VB-*piep* da draußen.
Außerdem solltest du ComVisible für die Assembly auf false setzen, un nur für einzelne Typen einschalten.
Du willst ja nur ein Subset der Assembly für COM sichtbar machen, die meisten dinge würde nämlich gar nicht einfach so in COM laufen...

Bleistift(Chrome, kein D.Net):
Delphi-Quellcode:
type
  [ComVisible(true)]
  [Guid("5E95FD65-3125-4494-AC8C-A1AFF186AA04")]
  [InterfaceType(ComInterfaceType.InterfaceIsDual)]
  ISample = public interface
     // DispId is wichtig, da sonst in späteren Versionen
     // die falsche Methode aufgerufen werden könnte
    [DispId(0)]
    property SomeValue : String read write;
    [DispId(1)]
    method AddToSomeValue(someString : String);
  end;

  [ComVisible(true)]
  [ComDefaultInterface(typeOf(ISample))]
  Sample = public class(ISample)
  public
    property SomeValue: System.String;
    method AddToSomeValue(someString: System.String);

    constructor; empty;
    constructor(someValue : String);
  end;
 
implementation

constructor Sample(someValue : String);
begin
  self.SomeValue := someValue;
end;

method Sample.AddToSomeValue(someString : System.String);
begin
  SomeValue := SomeValue + someString;
end;
Das lässt sich dann so in Delphi benutzen:
Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  ActiveX,
  ClassLibrary1_TLB;
var
  test : TSample;
begin
  CoInitialize(nil);
  test := TSample.Create(nil);
  test.SomeValue := 'abc';
  test.AddToSomeValue('def');

  Writeln(test.SomeValue);
end.

Elvis 13. Feb 2008 11:04

Re: C#.Net2.0 DLL in Delphi2007 nutzen (Com)?
 
Achso, für einfache Dinge, könnte auch ein "[ClassInterface(ClassInterfaceType.AutoDual)]" direkt an der Klasse reichen.
Aber meistens will man das nicht.
Ein extra Interface erlaubt, dass man für COM ein paar Dinge COM-verständlicher machen kann...


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:59 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz