Delphi应用程序

时间:2015-12-09 12:35:36

标签: c# delphi event-handling portable-class-library class-library

我正在尝试使用Delphi应用程序中的Proximity API在C#上编写的类库中。目前设备初始化工作正常,但我不知道如何从Proximity设备事件(DeviceArrived,DeviceDeparted)返回一些东西。这是我的代码:

C#部分

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Windows.Networking.Proximity;
using Windows.Storage.Streams;

namespace hsProximity
{
    [ComVisible(true), Guid("B6597243-2CC4-475B-BF78-427BEFE77346"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IHSCallbackHandler
    {
        void DeviceArrived(String AMessage);
    }

    [ComVisible(true), Guid("81C99F84-AA95-41A5-868E-62FAC8FAC263"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IHSProximityInterface
    {
        bool doInitialise(out String AMessage);
        void SetHandler(IHSCallbackHandler handler);
        void doGetUID(out String AUID);
    }

    [ClassInterface(ClassInterfaceType.None), ComVisible(true)]
    public class MainClass : IHSProximityInterface
    {
        public ProximityDevice proximityDevice;
        public List<NdefRecord> recordList;
        public String mUID = "";


        private IHSCallbackHandler handler;
        public void SetHandler(IHSCallbackHandler handler) 
        { 
            this.handler = handler; 
        }

        public void doGetUID(out String AUID)
        {
            AUID = mUID;
        }

        public bool doInitialise(out String AMessage)
        {
            recordList = new List<NdefRecord>();
            proximityDevice = ProximityDevice.GetDefault();

            if (proximityDevice != null)
            {
                proximityDevice.DeviceArrived += ProximityDeviceArrived;
                proximityDevice.DeviceDeparted += ProximityDeviceDeparted;
                proximityDevice.SubscribeForMessage("NDEF", MessageReceivedHandler);
                AMessage = "Proximity device initialized. ID: " + proximityDevice.DeviceId;
                return true;
            }
            else
            {
                AMessage = "Failed to initialize proximity device.";
                return false;
            }
        }

        public void ProximityDeviceArrived(ProximityDevice sender)
        {
            //mCardStatusMsg = "Proximate device arrived.";
        }

        public void ProximityDeviceDeparted(ProximityDevice sender)
        {
            //mCardStatusMsg = "Proximate device departed.";
            mUID = "";
        }

        public void MessageReceivedHandler(ProximityDevice sender, ProximityMessage message)
        {
            recordList.Clear();
            mUID = ParseNDEF(message);
            handler.DeviceArrived(mUID);
        }

TLB文件的一部分

uses Winapi.Windows, mscorlib_TLB, System.Classes, System.Variants, System.Win.StdVCL, Vcl.Graphics, Vcl.OleServer, Winapi.ActiveX;


const
  // TypeLibrary Major and minor versions
  hsProximityMajorVersion = 1;
  hsProximityMinorVersion = 0;

  LIBID_hsProximity: TGUID = '{DEB4779B-F6A7-37F2-8A63-1A2F99A22A73}';

  IID_IHSCallbackHandler: TGUID = '{B6597243-2CC4-475B-BF78-427BEFE77346}';
  IID_IHSProximityInterface: TGUID = '{81C99F84-AA95-41A5-868E-62FAC8FAC263}';
  CLASS_MainClass: TGUID = '{0333D76F-F345-3085-9F00-F816654CC89C}';
  IID__NdefRecord: TGUID = '{7C5F471E-68F8-3065-888E-95AB112B35B6}';
  CLASS_NdefRecord: TGUID = '{9F2A8192-94F9-3D0C-AD5F-D05D769DEF4B}';
type

  IHSCallbackHandler = interface;
  IHSProximityInterface = interface;
  _NdefRecord = interface;
  _NdefRecordDisp = dispinterface;

  MainClass = IHSProximityInterface;
  NdefRecord = _NdefRecord;

  IHSCallbackHandler = interface(IUnknown)
    ['{B6597243-2CC4-475B-BF78-427BEFE77346}']
    function DeviceArrived(const AMessage: WideString): HResult; stdcall;
  end;


  IHSProximityInterface = interface(IUnknown)
    ['{81C99F84-AA95-41A5-868E-62FAC8FAC263}']
    function doInitialise(out AMessage: WideString; out pRetVal: WordBool): HResult; stdcall;
    function SetHandler(const handler: IHSCallbackHandler): HResult; stdcall;
  end;


  _NdefRecord = interface(IDispatch)
    ['{7C5F471E-68F8-3065-888E-95AB112B35B6}']
  end;


  _NdefRecordDisp = dispinterface
    ['{7C5F471E-68F8-3065-888E-95AB112B35B6}']
  end;

  CoMainClass = class
    class function Create: IHSProximityInterface;
    class function CreateRemote(const MachineName: string): IHSProximityInterface;
  end;

 CoNdefRecord = class
    class function Create: _NdefRecord;
    class function CreateRemote(const MachineName: string): _NdefRecord;
  end;

德尔福部分

type
  THandler = class(TObject, IUnknown, IHSCallbackHandler)
  private
    FRefCount: Integer;
  protected
    function DeviceArrived(const AMessage: WideString): HResult; stdcall;

    function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  public
    property RefCount: Integer read FRefCount;
  end;
...
FProximity : IHSProximityInterface;
...
    procedure TFormMenu.TestProximityDllBtnClick(Sender: TObject);
var
  vUID : WideString;
  vMessage : WideString;
  vInitResult : WordBool;
begin
  if (FProximity <> nil) then begin
    OleCheck(FProximity.doGetUID(vUID));
    hsinfo(vUID);
  end else begin
    if (not Assigned(FProximity)) then begin
      FProximity := CreateComObject(CLASS_MainClass) as IHSProximityInterface;
    end;

    OleCheck(FProximity.doInitialise(vMessage, vInitResult));
    hsinfo(vMessage);

    FHandler := THandler.Create();
    OleCheck(FProximity.SetHandler(FHandler));
  end;
end;

function THandler.DeviceArrived(const AMessage: WideString): HResult;
begin
  showmessage(AMessage);
  result := 0;
end;

所以目前doInitialise工作正常并且支持我的设备ID,DeviceArrived也可以工作,但Delphi应用程序端没有任何反应。有人可以帮助我做错了吗?

1 个答案:

答案 0 :(得分:0)

我有点重新调整我的代码。所以这里的解决方案就像我想要的那样。

C#部分

FProximity : IHSProximityInterface;
...
procedure TFormMenu.TestProximityDllBtnClick(Sender: TObject);
var
  vMessage : WideString;
  vInitResult : WordBool;
begin
  if Assigned(FProximity) then exit;

  if (not Assigned(FProximity)) then begin
    FProximity := CreateComObject(CLASS_MainClass) as IHSProximityInterface;
  end;

  if Assigned(FProximity) then begin
    FProximity.doInitialise(LongInt(@NDEFReceived), LongInt(@DeviceStatusChanges), vMessage, vInitResult);
    log(vMessage, 'NFC');
  end else begin
    log('Can''t create proximity class', 'NFC');
  end;
end;

procedure NDEFReceived(AMsg: PChar); stdcall;
begin
  log(AMsg, 'NFC');
end;

procedure DeviceStatusChanges(AStatus: integer); stdcall;
begin
  if (AStatus = 0) then begin
    log('Proximity device departed.', 'NFC');
  end else begin
    log('Proximity device arrived.', 'NFC');
  end;
end;

德尔福部分

{{1}}