Calling C DLL from C#

后端 未结 4 1345
悲哀的现实
悲哀的现实 2020-12-14 23:47

I am trying to call a C DLL from C#, but I\'m not having any joy. The documentation for the DLL provides an example function delaration for VB that looks like;



        
相关标签:
4条回答
  • 2020-12-14 23:59

    Looks like you aren't the only one to encounter that issue, have you tried StdCall? That worked for this fellow: http://www.mail-archive.com/delphi@ns3.123.co.nz/msg01227.html

    0 讨论(0)
  • 2020-12-15 00:04

    I found the reason for my failed attempts by utilising a tool called; Microsoft(R) P/Invoke Interop Assistant as suggested by an answer on this thread.

    I utilised this tool to input some of the C function prototypes and get it to generate the required C# prototype on my behalf. The C prototype looked like the following;

    long __stdcall TransProjPt(LPSTR psGridFile, long lDirection, double dEasting, double
    dNorthing, long lZone, double* pdEastNew, double* pdNorthNew, double* pdEastAcc,
    double* pdNorthAcc) 
    

    When entering this into the Interop assistant tool, it showed that rather than using longs (as I had done in my original question), these should be declared as an int. It produced the following output that meant my code above now worked as I'd hoped. Yay.

        /// Return Type: int
        ///psGridFile: LPSTR->CHAR*
        ///lDirection: int
        ///dEasting: double
        ///dNorthing: double
        ///lZone: int
        ///pdEastNew: double*
        ///pdNorthNew: double*
        ///pdEastAcc: double*
        ///pdNorthAcc: double*
        [System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="TransProjPt", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
    public static extern  int TransProjPt([System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] System.Text.StringBuilder psGridFile, int lDirection, double dEasting, double dNorthing, int lZone, ref double pdEastNew, ref double pdNorthNew, ref double pdEastAcc, ref double pdNorthAcc) ;
    

    Thanks for everyones help with this.

    0 讨论(0)
  • 2020-12-15 00:10

    Try changing string sGridFile to StringBuilder sGridFile

    C++ has so many different kinds of strings that marshaling strings between manage and unmanaged code can be tricky.

    0 讨论(0)
  • 2020-12-15 00:17

    You may want to define your c# signatures using marshalling attributes for your string parameters.

    [DllImport(@"c:\GDAit.dll")]
    public static extern long TransGeogPt([MarshalAs(UnmanagedType.LPStr)] string sGridFile, long lDirection, double dLat, double dLong, ref double pdLatNew, ref double pdLongNew, ref double pdLatAcc, ref double pdLongAcc);
    
    [DllImport(@"c:\GDAit.dll")]
    public static extern long TransProjPt([MarshalAs(UnmanagedType.LPStr)] string sGridFile, long lDirection, double dLat, double dLong, long lZone, ref double pdLatNew, ref double pdLongNew, ref double pdLatAcc, ref double pdLongAcc);
    

    I'll also piggy-back on Mark Sowul's answer and say try calling with StdCall instead of Cdecl.

    Also, as a precaution, I'd probably double-check to make sure that the compiler is set to compile x86 code, in case its compiling for 64-bit.

    0 讨论(0)
提交回复
热议问题