Thread: C# call Delphi DLL Error.

  1. #1
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184

    C# call Delphi DLL Error.

    Im trying to call from C# .net 3.5 a old Delphi DLL.

    DLL, Syntax (Delphi):

    Code:
    function WLePesoControlado8540(const Conexao,NLeiturasEstaveis,Timeout: integer; Bruto, Liquido, Tara,Motion,Print,PesoMinimoStick out tongueChar):Integer; stdcall;external 'MGB.DLL';
    C# Code:
    Code:
    [DllImport("MGB.dll", EntryPoint = "WLePesoControlado8540", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] 
            private static extern int WLePesoControlado8540(int conexao, int nleiturasestaveis, int timeout, StringBuilder bruto, StringBuilder liquido, StringBuilder tara, StringBuilder motion, StringBuilder print, string peso_minimo); 
     
    ........ 
     
     public bool RecebePeso() 
            { 
                string strBruto, strLiquido, strTara, strMotion, strPrint; 
                string strPesoMin = "-1000"; 
     
                StringBuilder strbBruto = new StringBuilder(10); 
                StringBuilder strbLiquido = new StringBuilder(10); 
                StringBuilder strbTara = new StringBuilder(10); 
                StringBuilder strbMotion = new StringBuilder(10); 
                StringBuilder strbPrint = new StringBuilder(10); 
     
                iRetorno = WLePesoControlado8540(iConexao, 0, 10, strbBruto, strbLiquido, strbTara, strbMotion, strbPrint, strPesoMin); 
     
                strBruto = strbBruto.ToString(); 
                strLiquido = strbLiquido.ToString(); 
                strTara = strbTara.ToString(); 
                strMotion = strbMotion.ToString(); 
                strPrint = strbPrint.ToString(); 
     
    .............
    Exception:

    See the end of this message for details on invoking
    just-in-time (JIT) debugging instead of this dialog box.

    ************** Exception Text **************
    System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    at Porter.Balanca.WLePesoControlado8540(Int32 conexao, Int32 nleiturasestaveis, Int32 timeout, StringBuilder& bruto, StringBuilder& liquido, StringBuilder& tara, StringBuilder& motion, StringBuilder& print, String peso_minimo)
    at Porter.Balanca.RecebePeso() in C:\Documents and Settings\Sergio\Meus documentos\Visual Studio 2008\Projects\Porter\Porter\Balanca.cs:line 112
    at Porter.Porter.tmrPegaPeso_Tick(Object sender, EventArgs e) in C:\Documents and Settings\Sergio\Meus documentos\Visual Studio 2008\Projects\Porter\Porter\Porter.cs:line 75
    at System.Windows.Forms.Timer.OnTick(EventArgs e)
    at System.Windows.Forms.Timer.TimerNativeWindow.WndPr oc(Message& m)
    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    Please, Somebody can help me ?

  2. #2
    Registered User
    Join Date
    Aug 2008
    Posts
    188
    what is a "out tongueChar"?

  3. #3
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    sorry

    is pChar not tongueChar

  4. #4
    Registered User
    Join Date
    Aug 2008
    Posts
    188
    hmmm, i believe a StringBuilder is unicode, so if your original application is not unicode that might cause problems. look into using fixed arrays and MarshalAs attribute for your p/invoke signature to match it up perfectly.

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    You won't be able to do it directly. Delphi uses the "register" calling convention by default - which .NET does not support. The Microsoft C/C++ compiler doesn't even support it.

    Options:
    1) Recompile the Delphi DLL with an compatible calling convention
    2) Create a "bridge" DLL in Delphi that exposes a function (with a compatible calling convention) which simply forward the call to the other DLL (using Delphi calling convention)
    3) Create a "bridge" DLL in C with the appropriate inline assembly to forward the call

    http://en.wikipedia.org/wiki/X86_cal...tions#fastcall
    http://msdn.microsoft.com/en-us/libr...onvention.aspx

    gg

  6. #6
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    I Can't recompile DLL, it's not mine.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by sergioms View Post
    I Can't recompile DLL, it's not mine.
    So you need a "bridge" or "converter" DLL that makes the C# and Delphi code compatible - it's not an entirely unusual scenario.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Im Using Marshal.

    IntPtr ptrPesoMin = Marshal.StringToHGlobalAnsi(strPesoMin);

    iRetorno = WLePesoControlado8540(iConexao, 0, 10, ref strbBruto, ref strbLiquido, ref strbTara, ref strbMotion, ref strbPrint, ptrPesoMin);

    But not good results, the same error continue.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Did you READ and UNDERSTAND CodePlug's post?

    If you did, you wouldn't be asking the questions you do, I would think.

    If you didn't, please do, and ask relevant questions if there is something you don't understand. Basically, you can not call a Delphi DLL compiled with default Delphi settings from C# - you need a translation somewhere between the two.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Ok matsp,

    But, I'm using some methods to translate.

    Like...

    pchar -> StringBuilder
    string -> IntPtr

    CallingConvention = CallingConvention.StdCall
    CharSet = CharSet.Ansi

    I was read in articles, and msdn, and another guys send tips to me.

    I have another program communicating with Delphi DLL using C#, but not using pchar.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    But: The calling convention is (according to CodePlug) different - so unless your Delphi DLL is actually compiled with StdCall calling convention, it will not work.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Im not sure this,

    I have a old Application using Powerbuilder and I call this same DLL.
    Using Blob type.

    And Im sure C# can access directly this DLL,

    I use 4 functions of this DLL, using string, int

    But this function WLePesoControlado8540 use pChar, and this have an error

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So, have you checked the calling convention of the DLL functions? If the calling convention is fastcall, then it's not going to work. If the calling convention is stdcall, then it should work and something else is the problem.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Ok, I manual of DLL owner say:

    WLePesoControlado8540

    Leitura do peso mostrado no display, com alguns controles. Para receber o peso "on-line" na balança, é necessário chamar de tempos e tempos esta função.

    Syntax (Delphi):

    function WLePesoControlado8540(const Conexao,NLeiturasEstaveis,Timeout: integer; Bruto,
    Liquido, Tara,Motion,Print,PesoMinimo:PChar):Integer; stdcall;external 'MGB.DLL';

    -----

    I Have Created another DLL with same code (function) in Delphi, and call from C#.
    And the Results is OK,

    I Will contact the DLL owner.

  15. #15
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    I missed that "stdcall" at the end of the Delphi function - sorry for the confusion.

    So if the calling convention is the same, then a parameter/type miss-match seems more likely.
    StringBuilder does seem to be the correct type to use - according to this: http://msdn.microsoft.com/en-us/libr...stringsanchor3

    Here's what I would try first:
    1) change "string peso_minimo" to StringBuilder - I see no reason for it to be different
    2) give all the StringBuilder's more than 10 - just to be safe

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. Avoiding Global variables
    By csonx_p in forum Windows Programming
    Replies: 32
    Last Post: 05-19-2008, 12:17 AM
  3. file reading
    By gunghomiller in forum C++ Programming
    Replies: 9
    Last Post: 08-07-2007, 10:55 PM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. pointer to array of objects of struct
    By undisputed007 in forum C++ Programming
    Replies: 12
    Last Post: 03-02-2004, 04:49 AM