c# जेएलएल के साथ/बिना डेल्फी में सीएलआर होस्टिंग-उदाहरण




.net delphi (3)

यहाँ एक और विकल्प है

यह सी # कोड है और यहां तक ​​कि अगर आप अपने अप्रबंधित निर्यात का उपयोग नहीं करना चाहते हैं, तो यह अभी भी समझा जाएगा कि आईडीसीपैच (आईडीआईएसपीएफ़ बहुत धीमा है) के बिना बिना एमएसओसीईई (सीएलआर होस्टिंग सामग्री) का उपयोग कैसे करें।

using System;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;

namespace DelphiNET
{

   [ComVisible(true)]
   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
   [Guid("ACEEED92-1A35-43fd-8FD8-9BA0F2D7AC31")]
   public interface IDotNetAdder
   {
      int Add3(int left);
   }

   [ComVisible(true)]
   [ClassInterface(ClassInterfaceType.None)]
   public class DotNetAdder : DelphiNET.IDotNetAdder
   {
      public int Add3(int left)
      {
         return left + 3;
      }
   }

   internal static class UnmanagedExports
   {
      [DllExport("createdotnetadder", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
      static void CreateDotNetAdderInstance([MarshalAs(UnmanagedType.Interface)]out IDotNetAdder instance)
      {
         instance = new DotNetAdder();
      }
   }
}

यह डेल्फी इंटरफ़ेस घोषणा है:

type
  IDotNetAdder = interface
  ['{ACEEED92-1A35-43fd-8FD8-9BA0F2D7AC31}']
    function Add3(left : Integer) : Integer; safecall;
  end;

यदि आप अप्रबंधित निर्यात का उपयोग करते हैं, तो आप ऐसा कर सकते हैं:

procedure CreateDotNetAdder(out instance :  IDotNetAdder); stdcall;
  external 'DelphiNET' name 'createdotnetadder';

var
  adder : IDotNetAdder;
begin
  try
   CreateDotNetAdder(adder);
   Writeln('4 + 3 = ', adder.Add3(4));
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

जब मैं लार्स का नमूना बदलता हूं, तो यह ऐसा दिखेगा:

var
  Host: TJclClrHost;
  Obj: IDotNetAdder;
begin
  try
    Host := TJclClrHost.Create;
    Host.Start();
    WriteLn('CLRVersion = ' + Host.CorVersion);

    Obj := Host.DefaultAppDomain
               .CreateInstance('DelphiNET', 
                               'DelphiNET.DotNetAdder')
               .UnWrap() as IDotNetAdder;
    WriteLn('2 + 3 = ', Obj.Add3(2));

    Host.Stop();
  except
    on E: Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

इस मामले में आप "UnmanagedExports" वर्ग को सी # कोड से निकाल सकते हैं, ज़ाहिर है।

क्या कोई यहां एक उदाहरण पोस्ट कर सकता है कि डेल्फी में सीएलआर होस्ट कैसे किया जाए? मैंने यहां समान प्रश्न पढ़ा है लेकिन मैं जेसीएल का उपयोग नहीं कर सकता क्योंकि मैं इसे डेल्फी 5 में होस्ट करना चाहता हूं। धन्यवाद।

संपादित करें: फॉक्स प्रो में सीएलआर की मेजबानी के बारे में यह लेख आशाजनक दिखता है लेकिन मुझे नहीं पता कि डेल्फी से clrhost.dll का उपयोग कैसे किया जाए।

2 संपादित करें: मैं डेल्फी 5 आवश्यकता पर छोड़ देता हूं। अब मैं जेसीएल को डेल्फी 7 की कोशिश कर रहा हूं। लेकिन फिर से मुझे कोई उदाहरण नहीं मिला। यहां तक ​​कि मेरे पास अब तक क्या है:

मेरी सी # विधानसभा:

namespace DelphiNET
{
    public class NETAdder
    {
        public int Add3(int left)
        {
            return left + 3;
        }
    }
}

मैंने इसे DelphiNET.dll . DelphiNET.dll पर संकलित किया है

अब मैं डेल्फी से इस विधानसभा का उपयोग करना चाहता हूं:

uses JclDotNet, mscorlib_TLB;

procedure TForm1.Button1Click(Sender: TObject);
var
  clr: TJclClrHost;
  ads: TJclClrAppDomainSetup;
  ad: TJclClrAppDomain;
  ass: TJclClrAssembly;
  obj: _ObjectHandle;
  ov: OleVariant;
begin
  clr := TJclClrHost.Create();
  clr.Start;
  ads := clr.CreateDomainSetup;
  ads.ApplicationBase := 'C:\Delhi.NET';
  ads.ConfigurationFile := 'C:\Delhi.NET\my.config';
  ad := clr.CreateAppDomain('myNET', ads);
  obj := (ad as _AppDomain).CreateInstanceFrom('DelphiNET.dll', 'DelphiNET.NETAdder');
  ov := obj.Unwrap;
  Button1.Caption := 'done ' + string(ov.Add3(5));
end;

यह त्रुटि के साथ समाप्त होता है: EOleError: Variant एक स्वचालन ऑब्जेक्ट का संदर्भ नहीं देता

मैंने डेल्फी के साथ एक लंबे समय तक काम नहीं किया है, इसलिए मैं यहां फंस गया हूं ...

समाधान: COM दृश्यता में समस्या थी जो डिफ़ॉल्ट रूप से नहीं है यह सही .net विधानसभा है:

namespace DelphiNET
{
    [ComVisible(true)]
    public class NETAdder
    {
        public int Add3(int left)
        {
            return left + 3;
        }
    }
}

महत्वपूर्ण लेख:

डेल्फी से एनएटी के साथ काम करते समय, यह महत्वपूर्ण है Set8087CW($133F); अपने कार्यक्रम की शुरुआत में (यानी Application.Initialize; से पहले। प्रारंभ करें Application.Initialize; ) डेल्फी ने डिफ़ॉल्ट रूप से फ़्लोटिंग प्वाइंट अपवाद सक्षम किया है ( यह देखें) और सीएलआर उन्हें पसंद नहीं करता है। जब मैंने उन्हें सक्षम किया था, तो मेरे कार्यक्रम को अजीब से मुक्त कर दिया गया था।


हेयर यू गो:

program CallDotNetFromDelphiWin32;

{$APPTYPE CONSOLE}

uses
  Variants, JclDotNet, mscorlib_TLB, SysUtils;

var
  Host: TJclClrHost;
  Obj: OleVariant;
begin
  try
    Host := TJclClrHost.Create;
    Host.Start;
    WriteLn('CLRVersion = ' + Host.CorVersion);

    Obj := Host.DefaultAppDomain.CreateInstance('DelphiNET', 'DelphiNET.NETAdder').UnWrap;
    WriteLn('2 + 3 = ' + IntToStr(Obj.Add3(2)));

    Host.Stop;
  except
    on E: Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

नोट: मानता है कि DelphiNET.dll में DelphiNET.NETAdder प्रकार और Add3 विधि Comvisible है। रॉबर्ट के लिए धन्यवाद

अपडेट करें :

प्रतिबिंब का उपयोग करते समय आपको कॉमविज़िबल विशेषता की आवश्यकता नहीं है अगला उदाहरण यहां तक ​​कि कॉमवेविबल के बिना भी काम करता है।

Assm := Host.DefaultAppDomain.Load_2('NetAddr');
T := Assm.GetType_2('DelphiNET.NETAdder');
Obj := T.InvokeMember_3('ctor', BindingFlags_CreateInstance, nil, null, nil);
Params := VarArrayOf([2]);
WriteLn('2 + 3 = ' + IntToStr(T.InvokeMember_3('Add3', BindingFlags_InvokeMethod, nil, Obj, PSafeArray(VarArrayAsPSafeArray(Params)))));

वर्ग comvisible होना चाहिए जो कि मामले में नहीं हो सकता है यदि आपके पास संपूर्ण विधानसभा के लिए अनुकूल है (गलत)

.Net वर्ग डिफ़ॉल्ट रूप से IDispatch संगत होंगे, इसलिए आपके नमूने को ठीक से काम करना चाहिए, यदि क्लास वास्तव में कम है।

लेकिन इसे पहले नंगे न्यूनतम करने के लिए नीचे पट्टी। अपने exe को उसी फ़ोल्डर में अपने .Net विधानसभा के रूप में रखें और कॉन्फ़िग फ़ाइल और एप्लिकेशन बेस को छोड़ दें।

इससे पहले कि कुछ मिला हो, अपवाद happesn यहाँ, सही?

 ov := obj.Unwrap;




host