Announcement

Collapse
No announcement yet.

call PB DLL from C#

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    call PB DLL from C#


    I work for a company that makes heat exchangers and I have written a PowerBasic DLL that helps our customers to select the right exchanger.
    Now a new customer want an ActiveX DLL instead of a PowerBasic DLL because he thinks he will have problems to call the DLL from C# (and he knows how to use ActiveX DLLs). I have promised him to try to find the right way to "declare" and call my DLL in C# (so I do not have to write an ActiveX DLL)

    In PowerBasic the subs in the DLL look like this:
    Code:
     SUB Get_Calculation(B1 AS BYTE, B2 AS BYTE, HeatexIn AS DOUBLE, _
     sHeatexType AS ASCIIZ, B3 AS BYTE, B4 AS BYTE, HeatexOut AS DOUBLE)
     EXPORT
    
     SUB Get_Price (B1 AS BYTE, B2 AS BYTE, PriceIn AS DOUBLE, _
     sHeatexType AS ASCIIZ, B3 AS BYTE, B4 AS BYTE, PriceOut AS DOUBLE,
     sArtCode AS ASCIIZ) EXPORT
    In VB6 declarations of the DLL look like this:
    Code:
     Declare Sub Get_Calculation Lib "HEATEX32.DLL" Alias
     "GET_CALCULATION" _ (b1 As Byte, b2 As Byte, heatexin As Double,
     ByVal X$, _ B3 As Byte, b4 As Byte, heatexout As Double)
    
     Declare Sub Get_Price Lib "HEATEX32.DLL" Alias "GET_PRICE" _
     (b1 As Byte, b2 As Byte, pricein As Double, ByVal X$, _
     B3 As Byte, b4 As Byte, priceout As Double, ByVal Y$)
    Does anybody know the subs should be called in C#?

    Best Regards

    Krister Olsson



    ------------------

    #2
    Try this

    Code:
    // using statments here...
    using System;
    using System.Runtime.InteropServices;
    
    
    // In your public declarations part of your class
    
    public class Myclass
    {
    
        [DllImport("HEATEX32.DLL",SetLastError=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
        public static extern void Get_Calculation( 
                byte b1, byte b2, double heatexin, 
                string X, byte B3,
    	    byte b4, double heatexout);
        public static extern void Get_Price(
                byte b1, byte b2, double PriceIn, 
    	    string X, byte B3, Byte b4, 
                double Priceout, string Y);
    
     
    
       protected override void MyMethod()
       {
    
       // Declare and initialize the appropriate variables
           // Call the subs
           Get_Calculation(b1, b2 heatexin, x, B3, b4, heatexout);
           Get_Price(b1, b2, PriceIn, X, B3, b4, Priceout, Y);
    
       }
      }
    If you want more information look in the help under DllImport statement.

    Hope this helps!

    - Brad

    ------------------




    [This message has been edited by Brad McLane (edited April 22, 2004).]

    Comment


      #3
      Well, no.

      Look up "C" in the PB/Win help index for general information.

      PB passes parameters BYREF by default. C/C++ passes BYVAL always,
      so you will need to adjust BYREF parameters to use pointers.

      PB has SUBs and FUNCTIONs. C/C++ only has functions. A function
      that doesn't return a value is shown as returning "void".

      C++ compilers apply "name decoration", which means that they mangle
      the function names artistically, so as to reflect the nature of the
      parameters passed to the function. To avoid this, you need to declare
      the functions using the C convention rather than the C++ convention.

      PB exports symbol names in all-caps, by default. C/C++ is case-sensitive,
      so you need to match the capitalization exactly. Let me make that quite
      clear: everything in C/C++ is case-sensitive, so you need to match the
      capitalization exactly.

      PB include files are typically named with a .inc file extension. The
      C convention is to use .h.

      I'll presume that the standard Windows typedefs and macros are present
      in the C/C++ program, as part of an earlier #include.

      So, we'll figure that you'll create a heatex32.h file, something like
      this:
      Code:
      // HeatEx32.dll copyright (c) 2004 Krister Olsson [or whatever]
      //
      
      #ifndef HEATEX32_H     // avoid processing more than once
      
      #define HEATEX32_H
      
      #ifdef __cplusplus
      extern "C" {
      #endif
      
      
      void GET_CALCULATION (BYTE * B1, BYTE * B2, double * HeatexIn,
        LPSTR sHeatexType, BYTE * B3, BYTE * B4, double * HeatexOut);
      
      void GET_PRICE (BYTE * B1, BYTE * B2, double * PriceIn,
        LPSTR sHeatexType, BYTE * B3, BYTE * B4, double * PriceOut,
        LPSTR sArtCode);
      
      
      #ifdef __cplusplus
      }
      #endif
      
      #endif  // #ifndef HEATEX32_H
      The way these routines are called will depend on whether the customer
      is using LoadLibrary. They may find it more convenient to use an import
      library, which would let them make the calls without needing LoadLibrary
      (the way you're familiar with in PowerBASIC)-- but, creating an import
      library will take a little more work on your end. Try a forum search
      for "import library" for more information.

      ------------------
      Tom Hanlin
      PowerBASIC Staff

      Comment


        #4
        Tom,

        The question was about interfacing with c-sharp, not C plus plus.

        The way I described it is how you call "unmanaged" code from .NET C#.

        - Brad

        ------------------


        [This message has been edited by Brad McLane (edited April 27, 2004).]

        Comment


          #5
          Good point. I haven't tried making .dll declarations for C#. I expect
          that BYVAL vs BYREF and case sensitivity are still important, though.

          ------------------
          Tom Hanlin
          PowerBASIC Staff

          Comment

          Working...
          X
          😀
          🥰
          🤢
          😎
          😡
          👍
          👎