Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. Calling an exported Function - Issue with different calling convention in C#

Calling an exported Function - Issue with different calling convention in C#

Scheduled Pinned Locked Moved C#
helpc++questioncsharpdebugging
7 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    Vini Deep
    wrote on last edited by
    #1

    Hi, I have 2 methods exported from a dll, MyReader.dll

    typedef unsigned short  UINT16;
    typedef unsigned int UINT32;
    typedef unsigned char   UINT8;
    #define  CMYREADER_API   __declspec(dllexport)
     
    
    class CMYREADER_API CMyReader 
    {
     public:
          bool mapImage(UINT16 SectorSize, const char * FileOnHardDriveToMap);
          bool mapImage(UINT16 SectorSize, bool (* CallbackFunctionAddress)(UINT32 SectorToBeRead, UINT8 * SetToSectorData, bool IsLiteral));
    ....
    };
    

    How can I call the 2nd method from My C# Client? I have declared a delegate to pass as the 2nd argument to the function.

    [DllImport("MyReader.dll", EntryPoint ="?mapImage@CMYReader@@QAE_NGP6A_NIPAE_N@Z@Z",CallingConvention=CallingConvention.ThisCall)]
    private static extern System.Int32 mapImage(IntPtr inst,System.UInt16 SectorSize, ReadSectorDelegate CallbackFunctionAddress);
    

    But when I give the CallingConvention as CallingConvention.ThisCall, I get the following error. --------------------------- Microsoft Visual C++ Debug Library --------------------------- Debug Error! Program: E:\Vini\MyRdrTest\bin\Debug\MyRdrTest.exe Module: File: i386\chkesp.c Line: 42 The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. (Press Retry to debug the application) --------------------------- Abort Retry Ignore --------------------------- But if I change the callingConvention to **CallingConvention.StdCall**, it does not call the CallBack function. Is there any other way to implement this? What am I doing wrong here? Kindly help. Vini

    M H 2 Replies Last reply
    0
    • V Vini Deep

      Hi, I have 2 methods exported from a dll, MyReader.dll

      typedef unsigned short  UINT16;
      typedef unsigned int UINT32;
      typedef unsigned char   UINT8;
      #define  CMYREADER_API   __declspec(dllexport)
       
      
      class CMYREADER_API CMyReader 
      {
       public:
            bool mapImage(UINT16 SectorSize, const char * FileOnHardDriveToMap);
            bool mapImage(UINT16 SectorSize, bool (* CallbackFunctionAddress)(UINT32 SectorToBeRead, UINT8 * SetToSectorData, bool IsLiteral));
      ....
      };
      

      How can I call the 2nd method from My C# Client? I have declared a delegate to pass as the 2nd argument to the function.

      [DllImport("MyReader.dll", EntryPoint ="?mapImage@CMYReader@@QAE_NGP6A_NIPAE_N@Z@Z",CallingConvention=CallingConvention.ThisCall)]
      private static extern System.Int32 mapImage(IntPtr inst,System.UInt16 SectorSize, ReadSectorDelegate CallbackFunctionAddress);
      

      But when I give the CallingConvention as CallingConvention.ThisCall, I get the following error. --------------------------- Microsoft Visual C++ Debug Library --------------------------- Debug Error! Program: E:\Vini\MyRdrTest\bin\Debug\MyRdrTest.exe Module: File: i386\chkesp.c Line: 42 The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. (Press Retry to debug the application) --------------------------- Abort Retry Ignore --------------------------- But if I change the callingConvention to **CallingConvention.StdCall**, it does not call the CallBack function. Is there any other way to implement this? What am I doing wrong here? Kindly help. Vini

      M Offline
      M Offline
      Mike Dimmick
      wrote on last edited by
      #2

      You can't call class-based DLL exports like this from .NET. You must either change the DLL to provide flat exports (static or file-scope functions) or use COM interop. Stability. What an interesting concept. -- Chris Maunder

      H 1 Reply Last reply
      0
      • M Mike Dimmick

        You can't call class-based DLL exports like this from .NET. You must either change the DLL to provide flat exports (static or file-scope functions) or use COM interop. Stability. What an interesting concept. -- Chris Maunder

        H Offline
        H Offline
        Heath Stewart
        wrote on last edited by
        #3

        Yes you can, actually, but you need to have a class factory which creates an instance of the class (which gives you the IntPtr) that you pass as the first parameter of a P/Invoke method using CallingConvention.ThisCall.

        Microsoft MVP, Visual C# My Articles

        1 Reply Last reply
        0
        • V Vini Deep

          Hi, I have 2 methods exported from a dll, MyReader.dll

          typedef unsigned short  UINT16;
          typedef unsigned int UINT32;
          typedef unsigned char   UINT8;
          #define  CMYREADER_API   __declspec(dllexport)
           
          
          class CMYREADER_API CMyReader 
          {
           public:
                bool mapImage(UINT16 SectorSize, const char * FileOnHardDriveToMap);
                bool mapImage(UINT16 SectorSize, bool (* CallbackFunctionAddress)(UINT32 SectorToBeRead, UINT8 * SetToSectorData, bool IsLiteral));
          ....
          };
          

          How can I call the 2nd method from My C# Client? I have declared a delegate to pass as the 2nd argument to the function.

          [DllImport("MyReader.dll", EntryPoint ="?mapImage@CMYReader@@QAE_NGP6A_NIPAE_N@Z@Z",CallingConvention=CallingConvention.ThisCall)]
          private static extern System.Int32 mapImage(IntPtr inst,System.UInt16 SectorSize, ReadSectorDelegate CallbackFunctionAddress);
          

          But when I give the CallingConvention as CallingConvention.ThisCall, I get the following error. --------------------------- Microsoft Visual C++ Debug Library --------------------------- Debug Error! Program: E:\Vini\MyRdrTest\bin\Debug\MyRdrTest.exe Module: File: i386\chkesp.c Line: 42 The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. (Press Retry to debug the application) --------------------------- Abort Retry Ignore --------------------------- But if I change the callingConvention to **CallingConvention.StdCall**, it does not call the CallBack function. Is there any other way to implement this? What am I doing wrong here? Kindly help. Vini

          H Offline
          H Offline
          Heath Stewart
          wrote on last edited by
          #4

          You can actually P/Invoke class methods so long as you have a class factory to create an instance of that class. The problem here - like the exception text reads - is that your callback function uses a different calling convention. To be honest, I'm not really sure how you're going to get around this. I've never had to deal with callbacks in classes before (just calling methods on exported native classes). The StdCall shouldn't work since you need to push the class instance's address in the ECX register (which the first parameter in a ThisCall method is used for). Thus, you wouldn't really be calling a method but a function, treating it as if it were static. I did find this[^], however, which I hope proves helpful.

          Microsoft MVP, Visual C# My Articles

          V 1 Reply Last reply
          0
          • H Heath Stewart

            You can actually P/Invoke class methods so long as you have a class factory to create an instance of that class. The problem here - like the exception text reads - is that your callback function uses a different calling convention. To be honest, I'm not really sure how you're going to get around this. I've never had to deal with callbacks in classes before (just calling methods on exported native classes). The StdCall shouldn't work since you need to push the class instance's address in the ECX register (which the first parameter in a ThisCall method is used for). Thus, you wouldn't really be calling a method but a function, treating it as if it were static. I did find this[^], however, which I hope proves helpful.

            Microsoft MVP, Visual C# My Articles

            V Offline
            V Offline
            Vini Deep
            wrote on last edited by
            #5

            Heath Stewart wrote: You can actually P/Invoke class methods so long as you have a class factory to create an instance of that class. Is there any link that explains this? I cannot change the calling convention as the method exported is a member of the class and I need to pass the instance ptr of the class as the first argument to the method, to call the class methods. Is there any other way to call the class methods from the DLL? Will it help, if I change the callback method declaration in the C++ Dll to something else? like,

            bool mapImage(UINT16 SectorSize, 
              bool (*  __stdcall  CallbackFunctionAddress)(UINT32 SectorToBeRead, UINT8 * SetToSectorData, bool IsLiteral));
            

            To call the methods from the exported class, I have added two methods to the class: 1. To return the instance ptr of the class to the client and 2. To remove the instance of the class. Is this the correct way? Pls help... :confused: Vini

            H 1 Reply Last reply
            0
            • V Vini Deep

              Heath Stewart wrote: You can actually P/Invoke class methods so long as you have a class factory to create an instance of that class. Is there any link that explains this? I cannot change the calling convention as the method exported is a member of the class and I need to pass the instance ptr of the class as the first argument to the method, to call the class methods. Is there any other way to call the class methods from the DLL? Will it help, if I change the callback method declaration in the C++ Dll to something else? like,

              bool mapImage(UINT16 SectorSize, 
                bool (*  __stdcall  CallbackFunctionAddress)(UINT32 SectorToBeRead, UINT8 * SetToSectorData, bool IsLiteral));
              

              To call the methods from the exported class, I have added two methods to the class: 1. To return the instance ptr of the class to the client and 2. To remove the instance of the class. Is this the correct way? Pls help... :confused: Vini

              H Offline
              H Offline
              Heath Stewart
              wrote on last edited by
              #6

              You need class factory functions - either static class functions (I think that should work - never tried it) or C-style (or "decorated" C++ style) export functions. See a previous post where I covered this, http://www.codeproject.com/script/comments/forums.asp?msg=771919&forumid=1649&XtraIDs=1649&searchkw=ThisCall&sd=11%2F15%2F1999&ed=4%2F28%2F2004#xx771919xx[^].

              Microsoft MVP, Visual C# My Articles

              V 1 Reply Last reply
              0
              • H Heath Stewart

                You need class factory functions - either static class functions (I think that should work - never tried it) or C-style (or "decorated" C++ style) export functions. See a previous post where I covered this, http://www.codeproject.com/script/comments/forums.asp?msg=771919&forumid=1649&XtraIDs=1649&searchkw=ThisCall&sd=11%2F15%2F1999&ed=4%2F28%2F2004#xx771919xx[^].

                Microsoft MVP, Visual C# My Articles

                V Offline
                V Offline
                Vini Deep
                wrote on last edited by
                #7

                Tnx. I have seen that previous post of yours before. I am able to call the exported class methods. The issue with callback function, I think I have it right now, is by modifying the C++ DLL source. Added the __stdcall to the Callback method declaration. Is this okay?

                bool mapImage(UINT16 iSectorSize, bool (__stdcall * pCallback)(UINT32, UINT8 *, bool))
                

                Tnx for the help. Vini

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups