簡體   English   中英

如何在Delphi中使用DLL和.cs文件

[英]How to use a DLL and a .cs file in Delphi

我有一個用C ++編寫的DLL(幫助文件說是這樣),我有一個.cs文件,其中包含函數名稱,看起來像這樣:

    *// -------------- Part of MXIO.cs File -----
//#define _NET_WINCE
//==========================================================================================
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace MOXA_CSharp_MXIO
{
    class MXIO_CS
    {
        public const int SUPPORT_MAX_SLOT = 16;
        public const int SUPPORT_MAX_CHANNEL = 64;
        public const int SupportMaxChOfBit  = SUPPORT_MAX_CHANNEL>>3;
        //
#if _NET_WINCE
        [StructLayout(LayoutKind.Explicit, Size = 4)]
#else
        [StructLayout(LayoutKind.Explicit, Size = 4, Pack = 1)]
#endif

        //V1.2 OPC Tag DATA Struct
#if _NET_WINCE
        [StructLayout(LayoutKind.Sequential)]
#else
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
#endif
        public struct _IOLOGIKSTRUCT
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] BytMagic;
            public UInt16 wVersion;         // struct define of version 1.0.0
            public UInt16 wLength;
            public UInt16 wHWID;            // for user to know which API to Read/write
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] dwSrcIP;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] BytSrcMAC;
            public byte BytMsgType;         // for AP side to known what kind of Message return
            public UInt16 wMsgSubType;
            //------------------------
            // tag timestamp
            public UInt16 wYear;
            public byte BytMonth;
            public byte BytDay;
            public byte BytHour;
            public byte BytMin;
            public byte BytSec;
            public UInt16 wMSec;
            //-------------------------
            public byte BytLastSlot;        //add to notice the last slot, Range 0-16, 0=>myself only
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = SUPPORT_MAX_SLOT)]
            public byte[] BytLastCh;
            //-------------------------
            // support up to 16 slots and 64 channels //size:5408 bytes
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = SUPPORT_MAX_SLOT * SUPPORT_MAX_CHANNEL)]
            public byte[] BytChType;    // channel I/O type
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = SUPPORT_MAX_SLOT)]
            public UInt16[] wSlotID;    // Slot Module ID
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = SUPPORT_MAX_SLOT * SupportMaxChOfBit)]
            public byte[] BytChNumber;  // bitwised¡A1=Enable¡A0=Disable
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = SUPPORT_MAX_SLOT * SUPPORT_MAX_CHANNEL)] //
            public _ANALOG_VAL[] dwChValue;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = SUPPORT_MAX_SLOT * SupportMaxChOfBit)]
            public byte[] BytChLocked;  // bitwised, 0=free, 1=locked
        }
        //
#if _NET_WINCE
        [StructLayout(LayoutKind.Sequential)]
#else
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
#endif
        public struct _ACTDEV_IO
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] BytSrcMAC;
            public Int32 iHandle;
        }
        //
#if _NET_WINCE
        [StructLayout(LayoutKind.Sequential)]
#else
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
#endif
        public struct _MODULE_LIST
        {
            public UInt16 nModuleID;    //Module ID of device
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] szModuleIP;   //Save IP address of device
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] szMAC;        //Save MAC address of device
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] szModuleIP1;  //Save 2nd IP address of device
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] szMAC1;       //Save 2nd MAC address of device
            public byte bytLanUse;      //0 -> Lan0, 1 -> Lan1
        }

        public delegate void pfnCALLBACK(IntPtr bytData, UInt16 wSize);

        public delegate void pfnTagDataCALLBACK( _IOLOGIKSTRUCT[] ios, UInt16[] wMutex);

        /**********************************************/
        /*                                            */
        /*     Ethernet Module Connect Command        */
        /*                                            */
        /**********************************************/
        [DllImport("MXIO_NET.dll")]
        public static extern int MXEIO_Init();

        [DllImport("MXIO_NET.dll")]
        public static extern void MXEIO_Exit();

        [DllImport("MXIO_NET.dll")]
        public static extern int MXEIO_Connect(byte[] szIP, UInt16 wPort, UInt32 dwTimeOut, Int32[] hConnection);

        [DllImport("MXIO_NET.dll")]
        public static extern int MXEIO_Disconnect( Int32 hConnection );

        [DllImport("MXIO_NET.dll")]
        public static extern int MXEIO_CheckConnection( Int32 hConnection, UInt32 dwTimeOut, byte[] bytStatus );

        /***********************************************/
        /*                                             */
        /*              General Command                */
        /*                                             */
        /***********************************************/
        [DllImport("MXIO_NET.dll")]
        public static extern int MXIO_GetDllVersion();

        [DllImport("MXIO_NET.dll")]
        public static extern int MXIO_GetDllBuildDate();
        /*************************************************/
        /*                                               */
        /*                  Error Code                   */
        /*                                               */
        /*************************************************/
        public const int MXIO_OK = 0;
        public const int ILLEGAL_FUNCTION = 1001;
        public const int ILLEGAL_DATA_ADDRESS = 1002;

        /*************************************************/
        /*                                               */
        /*              Data Format Setting              */
        /*                                               */
        /*************************************************/
        /* Data length define   */
        public const int BIT_5 = 0x00;
        public const int BIT_6 = 0x01;
        public enum MXIO_ModuleDataIndex: int
        {
            //---------------------------------------------------------------------------
            MX_ML_MODULE_LIST_SIZE                          = 47,
            MX_ML_INDEX_WHWID                               = 0,
            MX_ML_INDEX_SZIP0                               = 2,    //SIZE:16 (STRING)
            MX_ML_INDEX_SZMAC0                              = 18,   //SIZE:6 (STRING)
            MX_ML_INDEX_SZIP1                               = 24,   //SIZE:16 (STRING)
            MX_ML_INDEX_SZMAC1                              = 40,   //SIZE:6 (STRING)
            MX_ML_INDEX_BYTLANUSE                           = 46
        };
        //---------------------------------------------------------------------------
    }
}*

我正在嘗試訪問DLL中的任何功能。 這是Delphi代碼:

type
  TMyCall = function: integer; stdcall;

const
  MYDLL = 'D:\DelphiProjects\DLL_Read\MXIO_NET.dll';

procedure TForm2.btnFncClick(Sender: TObject);
var
   i,j,k: integer;
   Handle: THandle;
   mCall : TMyCall;
begin
   // Load the library
   Handle := LoadLibrary(MYDLL);

   // If succesful ...
   if Handle <> 0 then
   begin
      // Assign function  from the DLL to the
      // function variable mCall
      @mCall := GetProcAddress(Handle, 'MXIO_GetDllVersion');
      // If successful
      if @mCall <> nil then
      begin
        Label3.Caption:= 'DLL version =' + IntToStr(mCall);
      end
      else
        Label3.Caption:= 'Function Not found';

      // Unload library
      FreeLibrary(Handle);
   end
   else
    Label3.Caption:= 'Version Handle = 0';
end;

問題: GetProcAddress失敗並返回nil。

我試圖將代碼分成最小和完整的部分,希望我這次能做。 現在,我正在考慮將.cs文件(至少其中的一部分)轉換為Delphi單元,然后從那里調用DLL函數。 我想知道是否有人對此有經驗? 我將不勝感激

這個問題有些困惑。 有大量的C#代碼沒有相應的Delphi代碼。 有人懷疑Delphi代碼是否確實表現出您聲稱確實存在的問題。

無論如何,假設您顯示的GetProcAddress調用確實失敗,那么問題很容易回答。 GetProcAddress有兩種故障模式:

  1. 提供的模塊手柄無效。
  2. 提供的過程名稱無效。

由於模塊句柄是通過調用LoadLibrary返回的,因此我們可以排除第1項。 如果LoadLibrary成功,則說明我們具有有效的模塊句柄。

因此,唯一的結論是所提供的過程名稱無效。 這意味着您已加載的DLL不會導出名為MXIO_GetDllVersion的函數。 您可以通過在GetProcAddress返回nil后立即調用GetLastError自己確認。 這樣做時,您將獲得值127 ,即ERROR_PROC_NOT_FOUND

您可以通過檢查DLL導出的函數名稱來確認這一點。 使用諸如Dependency Walker之類的工具來執行此操作。

關於您的Delphi代碼的另一處小意見。 您已將THandle用於模塊句柄,但這是錯誤的類型。 它不會影響行為,但是在語義上是錯誤的。 使用HMODULE

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM