none
C++\CLR Form Window als DLL erzeugen, Visual Studio 2010

    질문

  • Hallo

    ich habe eine -Projekt geöffnet Visual C++ -> CLR  -> Windows Forms-Anwendung .

    Das Projekt beinhaltet nur ein Form Window.

    Wenn ich das Projekt als DLL erstellen möchte, habe ich in den Einstellungen:

    Konfiguartionseigenschaften - > Allgemein - >  Konfigurationstyp auf: Dynamische Bibliothek(.dll) gestellt

    Beim Erzeugen der DLL bekomme ich folgenden Fehler:

    Hilfe2Dll.obj : fatal error LNK1306: Der DLL-Einstiegspunkt ""int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z)" kann nicht verwaltet sein; als systemeigen kompilieren.

     

    Kann mir jemand sagen was ich an den Eigenschaften des Projekts noch ändern muss ?

    Oder muss noch was im Code ergänzt werden ?

     

     

    2011년 12월 5일 월요일 오후 1:07

답변

  • Ja! Es gibt keinen anderen Weg als Reflection.

    Ob ich allerdings bei einem Addin System die UI auch auslagern würde um ShowDialog aufzurufen ist eine andere Frage...


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    • 답변으로 표시됨 biedego 2011년 12월 7일 수요일 오후 1:08
    2011년 12월 7일 수요일 오전 9:49

모든 응답

  • Eine DLL darf natürlich kein main haben.

    Die Funktionen der DLL müssen entweder über das Assembly mit .NET angesprungen werden, oder Du musst COM/Interop verwenden, oder einen nativen Einsprungpunkt (C++/CLI) bauen. Kommt eben darauf an, von wo Du diese DLL benutzten willst.

    Also Rückfrage: Von wo willst Du diese DLL benutzen?


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    2011년 12월 5일 월요일 오후 1:18
  • Hallo

    ich möchte DLL von einer anderen Windows Form Anwendung nutzen.

    Ich möchte die DLL über  LoadLibrary laden und anschließend das Fenster in der DLL aufrufen.

    Weis aber nicht ob das der richtige weg ist

     

     

     

    2011년 12월 5일 월요일 오후 1:39
  • Falscher Weg.

    In .NET verwendet man kein LoadLibrary. Hier müsstest Du mit Refelection und entsprechenden Intzerfaces arbeiten.

    Siehe:
    http://stackoverflow.com/questions/181901/reflection-net-how-to-load-dependencies


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    2011년 12월 5일 월요일 오후 2:00
  • ok

    angekommen ich verwende Assembly.Loadfile, sieht dann der C++ Code so aus ?

    Assembly^  assambly = Assembly::LoadFile("Hilfe.dll");

     

    habe aber nach wie vor das Problem das ich nicht weis wie ich mein Form Project einstellen muss um es als Assembly laden zu können

    um überhaupt erst mal eine DLL zu gekommen.

     

    2011년 12월 5일 월요일 오후 2:37
  • habe aber nach wie vor das Problem das ich nicht weis wie ich mein Form Project einstellen muss um es als Assembly laden zu können
    um überhaupt erst mal eine DLL zu gekommen.

    Dann erzeuge einfach ein neues Projekt (CLR Class-Library) und kopiere die entsprechenden Source-Bestandteile. Das ist einfacher als Dein bestehendes Projekt umzustellen.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    2011년 12월 5일 월요일 오후 2:44
  • Das Erstellen über  "neues Projekt (CLR Class-Library)" hat funktioniert.

    Ich habe jetzt eine DLL mit einem Form Window.

    Bleibt noch das Problem das Fenster aufzurufen.

    Wenn die DLL über "Assembly^  assambly = Assembly::LoadFile("C:\\Daten\\Hilfe.dll"); " geladen ist,

    wie kann ich dann die Form aufrufen ? 

     

    2011년 12월 5일 월요일 오후 3:28
  • Hi,

    du könntest dazu die CreateInstance Methode der Klasse Assembly benutzen. Damit hättest du schon dein Forms Objekt und kannst damit "hantieren".

    Viele Grüße
    Holger M. Rößler


    Kaum macht man es richtig, schon funktioniert es
    2011년 12월 5일 월요일 오후 8:08
  • Wenn die DLL über "Assembly^  assambly = Assembly::LoadFile("C:\\Daten\\Hilfe.dll"); " geladen ist,
    wie kann ich dann die Form aufrufen ?

    Liest Du was man Dir schreibt?
    Ein Sample steht hier komplett drin:
    http://stackoverflow.com/questions/181901/reflection-net-how-to-load-dependencies


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    2011년 12월 6일 화요일 오전 7:04
  • Ja schon gelesen

    konnte den kompletten C# Code nicht in C++ umsetzten

    auch die Class IAddon kann ich nicht finden

     für ein Profi mag das kein Problem sein,  bin ich aber nicht.

    2011년 12월 6일 화요일 오전 8:20
  • konnte den kompletten C# Code nicht in C++ umsetzten

    Das sieht genauso aus. Aus den Objekten werden halt Handles mit dem ^.

    auch die Class IAddon kann ich nicht finden

    Das ist Deine Klasse, oder Dein Interface Deines Addons.

      für ein Profi mag das kein Problem sein,  bin ich aber nicht.

    Dann solltest Du evtl. noch etwas mehr Basiswissen ansammeln um auch solch Pseudo-Code/C# zu verstehen.

    Wie sieht denn jetzt Dein Code aus?


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    2011년 12월 6일 화요일 오전 8:59
  • Also

    ich habe unter Visulal C++ -> CLR -> Klassenbibliothek ein Projekt erstellt.

    Im Projekt habe ich unter Headerdateien ein Neues Element hinzugefügt -> Windows Form mit Namen Hilfe.

    Das Form Fesnter hat nur einen Button P01 den ich mit Close belegt habe.

    Habe die die Datein:

    Hilfe.h      // Form Window

    Hilfe.cpp  // Form Window

    KlassenDll.cpp // Wurde mit dem Projekt erzeugt

    KlassenDll.h    // Wurde mit dem Projekt erzeugt

     

    Ich möchte jetzt meine Hilfe Form öffnen

     

    // hilfe.h

    #pragma once

    namespace KlassenDll {

    using namespace System;

    using namespace System::ComponentModel;

    using namespace System::Collections;

    using namespace System::Windows::Forms;

    using namespace System::Data;

    using namespace System::Drawing;

    /// <summary>

    /// Zusammenfassung für Hilfe

    /// </summary>

    public ref class Hilfe : public System::Windows::Forms::Form

    {

    public:

    Hilfe(void)

    {

    InitializeComponent();

    //

    //TODO: Konstruktorcode hier hinzufügen.

    //

    }

     

    protected:

    /// <summary>

    /// Verwendete Ressourcen bereinigen.

    /// </summary>

    ~Hilfe()

    {

    if (components)

    {

    delete components;

    }

    }

    private: System::Windows::Forms::Button^  P01;

    private: System::Void P01_Click(System::Object^  sender, System::EventArgs^  e);

    private:

    /// <summary>

    /// Erforderliche Designervariable.

    /// </summary>

    System::ComponentModel::Container ^components;

     

    #pragma region Windows Form Designer generated code

    /// <summary>

    /// Erforderliche Methode für die Designerunterstützung.

    /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.

    /// </summary>

    void InitializeComponent(void)

    {

    this->P01 = (gcnew System::Windows::Forms::Button());

    this->SuspendLayout();

    // 

    // P01

    // 

    this->P01->Location = System::Drawing::Point(95, 211);

    this->P01->Name = L"P01";

    this->P01->Size = System::Drawing::Size(75, 23);

    this->P01->TabIndex = 0;

    this->P01->Text = L"Close";

    this->P01->UseVisualStyleBackColor = true;

    this->P01->Click += gcnew System::EventHandler(this, &Hilfe::P01_Click);

    // 

    // Hilfe

    // 

    this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);

    this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;

    this->ClientSize = System::Drawing::Size(292, 273);

    this->Controls->Add(this->P01);

    this->Name = L"Hilfe";

    this->Text = L"Hilfe";

    this->ResumeLayout(false);

     

    }

    #pragma endregion

    };

    }

     

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    // hilfe.cpp

    #include "StdAfx.h"

    #include "Hilfe.h"

     

    using namespace KlassenDll;

    System::Void Hilfe::P01_Click(System::Object^  sender, System::EventArgs^  e){

    this->Close();

    }

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    // KlassenDll.cpp 

    // Dies ist die Haupt-DLL.

     

    #include "stdafx.h"

     

    #include "KlassenDll.h"

     

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    // KlassenDll.h
    #pragma once
    using namespace System;
    namespace KlassenDll {
    public ref class Class1
    {
    // TODO: Die Methoden für diese Klasse hier hinzufügen.
    };
    }
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

     

     

    2011년 12월 6일 화요일 오전 9:49
  • Habe mir jetzt folgenden Aufruf definiert:
    Assembly^  assembly = Assembly::LoadFile(L"C:\\Daten\\KlassenDll.dll");
    Type^ tForm = assembly->GetType("Hilfe");
    Object^ Obj = Activator::CreateInstance(tForm);
    Application::Run((Form^) Obj);
    Ich bekomme aber beim Aufruf von "Object^ Obj = Activator::CreateInstance(tFrom);" einen System.ArgumentNullException.
    Habe beim Debuggen festgestellt das "tForm" keinen Wert hat.
    2011년 12월 6일 화요일 오후 12:17
  • Du hast den Namespace nicht berücksichtigt.

    IMHO müsste es "KlassenDLL.Hilfe" für GetType lauten.

    Siehe hier Beispiele:
    http://stackoverflow.com/questions/376105/using-assembly-gettypemycompany-class1-class2-returns-null


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    2011년 12월 6일 화요일 오후 12:57
  • Ok habe ich geändert

    tForm hat jetzt einen Wert und CreateInstance funktioniert jetzt.

    wenn ich jetzt "Application::Run((Form^) Obj);" aufrufe dann bekomme ich einen Exception "System.InvalidOperationException"

    mit folgender Meldung:

    "Das starten einer zweiten meldungsschleife auf einem einzelnen thread ist ein ungültiger vorgang. Verwenden sie form.showdialog."

    Forms werden ja normalaweise so aufgerufen:

    Form^ FromAusDLL = gcnew Hilfe;

    FromAusDLL->ShowDialog();

    muss im meinem Fall für Hilfe das Object (Obj)  verwendet werden  ?

     


    2011년 12월 6일 화요일 오후 2:27
  • Ich habe jetzt einen Weg gefunden um meine Form zu öffnen
    Assembly^  assembly = Assembly::LoadFile(L"C:\\Daten\\KlassenDll.dll");
    Type^         typeForm = assembly->GetType("KlassenDll.Hilfe");
    Object^      Obj           = Activator::CreateInstance(typeForm);
    Form^ KlassenDll_Form = safe_cast<Form^>(Obj);
            KlassenDll_Form->ShowDialog();
    kann mir jemand sagen ob das jetzt der richtige weg ist.
    2011년 12월 7일 수요일 오전 9:43
  • Ja! Es gibt keinen anderen Weg als Reflection.

    Ob ich allerdings bei einem Addin System die UI auch auslagern würde um ShowDialog aufzurufen ist eine andere Frage...


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    • 답변으로 표시됨 biedego 2011년 12월 7일 수요일 오후 1:08
    2011년 12월 7일 수요일 오전 9:49