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

时间:2015-12-31 15:09:42

标签: c# delphi dll

我有一个用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函数。我想知道是否有人有这方面的经验?我很感激任何帮助

1 个答案:

答案 0 :(得分:2)

这个问题有些混乱。有大量的C#代码没有相应的Delphi代码。人们想知道Delphi代码是否真的表现出你声称它的问题。

无论如何,假设您显示的GetProcAddress电话失败,那么这个问题很容易回答。 GetProcAddress有两种失败模式:

  1. 提供的模块句柄无效。
  2. 提供的程序名称无效。
  3. 我们可以排除第1项,因为调用LoadLibrary会返回模块句柄。如果LoadLibrary成功,那么我们知道我们有一个有效的模块句柄。

    因此,唯一的结论是提供的过程名称无效。这意味着您加载的DLL不会导出名为MXIO_GetDllVersion的函数。您可以在GetLastError返回GetProcAddress后立即致电nil来自行确认。执行此操作后,您将获得127的值THandle

    您可以通过检查DLL导出的函数名来确认这一点。使用ERROR_PROC_NOT_FOUND之类的工具来执行此操作。

    对Delphi代码的另一个小评论。您已将HMODULE用于模块句柄,但这是错误的类型。它不会影响行为,但在语义上是错误的。使用{{1}}。