accessing Delphi DLL import with C#

This is a discussion on accessing Delphi DLL import with C# within the C# Programming forums, part of the General Programming Boards category; Greetings I've asked before on other forums but so far I'm stumped. I have a Delphi DLL library that communicates ...

  1. #1
    Registered User
    Join Date
    Jul 2011
    Posts
    4

    accessing Delphi DLL import with C#

    Greetings

    I've asked before on other forums but so far I'm stumped.

    I have a Delphi DLL library that communicates with an MCU and it works fine as it is. However I'm not into pascal and would rather continue learning C#. I'm trying to use the Delphi DLL from within the C# structure as it already handles the communication with the mcu.

    List of functions and procedures provided by the DLL

    Code:
    Type TData = array [0..255] of byte;
    
    function Receive(Adr, Len: Integer): TData; stdcall;
    This dll reads data from the mcu.
    Adr= Starting address
    Len= Total length of the data being read
    The function returns a TData array where the item with index 0 contains the starting address and the item with index 1 contains the length of the data received.
    Following items (index 2 and higher) contain the data received. If the Receive operation fails, the length value returned in the array is set to zero.

    I have been trying the following without success.

    Code:
    [DllImport("mrds.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
    public static unsafe extern byte[] Receive(int Adr, int Len);
    
                
    private void btnReceive_Click(object sender, EventArgs e)
    {
        txtBox1.Text = "";
        StatusLbl1.Text = "";
        byte[] Data = new byte[8];
        int i, Adr =0x02, Len = 8;
        string s = "";
                for (i = 0; i <= 7; i ++ ) Data[i] = 0;
                Data[0] = 0x02;
                Data= Receive(Adr, Len);
                for (i = 1; i <= 8; i++)
                s = s + Data[i + 1].ToString();
                txtBox1.Text = s;
    }

    Everything works up to
    Code:
    Data= Receive(Adr, Len);
    where it returns an error "MarshalDirectiveException was unhandled"

    I'm lost, should I be using PInvoke or do I use a Marshal?

  2. #2
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,383
    Do you have any access to the Delphi source code?
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  3. #3
    Registered User
    Join Date
    Jul 2011
    Posts
    4
    Yes, I have the source code, same function
    Partial code shown as the owner asked it not be published.

    Delphi6
    Code:
    function Receive(Adr, Len: Integer): TData;
    function TDM1.Receive(Adr, Len: Integer): TData;
    var Output: TData;
    VaComm1.ReadChar(Ch)
    Output[Len+1]:=ReadByte(true);
    Result:=Output;
    
    end;

  4. #4
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,383
    Ok so, the first thing you might want to do is to change that function calling convention to stdcall. Delphi by default uses fastcall, but .net doesn't support it. This should limit any issues between your delphi dll and .net to datatype differences -- possibly eliminating the current error altogether. But unlikely. Still, it will guarantee you won't have other type of issues, like getting unexpected results between similar function calls.

    The error itself is well within PInvoke usage. So don't think it means you are using the wrong methodology. It means that it is encountering an attribute it doesn't support when marshaling data between the unmanaged and managed code. I suspect a data type conversion that isn't being supported. But I'm not actually sure. I'm suspecting the return type which isn't being properly mapped between the delphi Type TData and C# byte array. I'd probably try a unmanaged array here, before looking anywhere else.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  5. #5
    Registered User
    Join Date
    Jul 2011
    Posts
    4
    What if a new Function was created in the original mrds.dll that could store and export the
    Code:
    Result:=Output;
    ? Or am I looking at this the wrong way?

    The source mrds.dpr file identifies the Receive function as this
    Code:
    function Receive(Adr, Len: Integer): Unit1.TData; stdcall;
    
    begin
    
    Result:=DM1.Receive(Adr, Len);
    
    end;

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,383
    I wouldn't know. Don't ask me about Delphi. I have very little idea

    However I just now noticed from your initial post that the function is being declared as stdcall. So that's covered.
    If you don't want to use an unmanaged array, you could try to find some way to return from the delphi dll a true byte array, and not one wrapped inside a type. Do note however that I'm fishing here. I just know this is an attribute problem. You only work with two datatypes here. And Int can't be the problem because both languages share the same type properties.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    Registered User
    Join Date
    Jul 2011
    Posts
    4
    Thanks Mario

    I'll stick with a C# solution, the Send Function has no issues passing int and byte[] arrays through the delphi DLL so it must be a unmanaged Marshalling issue I am just not seeing for the Receive function.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Delphi DLL Problem, C++ hates Delphi strings
    By Cogman in forum C++ Programming
    Replies: 5
    Last Post: 09-08-2008, 07:32 PM
  2. accessing Delphi written file
    By Sha in forum C Programming
    Replies: 3
    Last Post: 12-12-2006, 11:50 PM
  3. Using C++ in delphi
    By ozzy34 in forum C++ Programming
    Replies: 1
    Last Post: 07-09-2004, 10:38 AM
  4. Delphi
    By face_master in forum A Brief History of Cprogramming.com
    Replies: 19
    Last Post: 04-29-2002, 05:22 AM
  5. Delphi??????
    By dayknight in forum A Brief History of Cprogramming.com
    Replies: 9
    Last Post: 04-25-2002, 06:42 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21