none
c# calls c++ function RRS feed

  • Question

  • I have try to use 

    [DllImport("kernel32.dll")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

    and Marshal.GetDelegateForFunctionPointer

    to get the c++ function pointer from c++ library in c# project.

    Everything seems okay, i can get non-zero IntPtr in both GetProcAddress and Marshal.GetDelegateForFunctionPointer.

    However, when i invoke the function, it would return IntPtr.Zero.

    When i debugging in Visual Studio Hosting, the function invokes successfully without any problems. However, when i run the program after build without Visual studio hosting, the function return IntPtr.Zero.

    Any one can help ??

    Tuesday, October 24, 2017 2:10 AM

All replies

  • BTW, MS says :
    // Note - do NOT use this to call methods.  Use P/Invoke, which will
    // do much better things w.r.t. marshaling, pinning memory, security
    // stuff, better interactions with thread aborts, etc.  

    But if I do a test with a random API, for example GetDefaultPrinter, this works for me (VS 2015, Windows 10) :

    IntPtr hModule = GetModuleHandle("Winspool.drv");
    if (hModule != IntPtr.Zero)
    {
        getDefaultPrinter_Delegate = CreateDelegate<GetDefaultPrinter_Delegate>(hModule, "GetDefaultPrinterW");
        StringBuilder sPrinterName = new StringBuilder(256);
        int nSize = sPrinterName.Capacity;
        int nLastWin32Error = 0;
        bool bReturn = getDefaultPrinter_Delegate(sPrinterName, ref nSize);
        nLastWin32Error = Marshal.GetLastWin32Error();
        if (!bReturn)
        {
            if (nLastWin32Error == ERROR_INSUFFICIENT_BUFFER)
            {
                StringBuilder pszBuffer = new StringBuilder(nSize);
                if (getDefaultPrinter_Delegate(pszBuffer, ref nSize))
                {
                    MessageBox.Show("Default Printer = " + pszBuffer);
                }
                else
                    throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            else
                throw new Win32Exception(nLastWin32Error);
        }
        else
            MessageBox.Show("Default Printer = " + sPrinterName.ToString());                
    }

    Declarations :

    [DllImport("Kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern IntPtr GetProcAddress(IntPtr hModule, String lpProcName);
    
    private static DT CreateDelegate<DT>(IntPtr hModule, String entryPointName)
    {
        IntPtr entryPoint = GetProcAddress(hModule, entryPointName);
        if (IntPtr.Zero == entryPoint)
            throw new EntryPointNotFoundException(entryPointName);
        return (DT)(Object)Marshal.GetDelegateForFunctionPointer(entryPoint, typeof(DT));
    }
    
    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    private delegate bool GetDefaultPrinter_Delegate(StringBuilder pszBuffer, ref int pcchBuffer);
    
    public const int ERROR_INSUFFICIENT_BUFFER = 122;
    private static GetDefaultPrinter_Delegate getDefaultPrinter_Delegate;


    • Edited by Castorix31 Tuesday, October 24, 2017 6:50 AM
    Tuesday, October 24, 2017 6:45 AM
  • But why the function invokes successfully under visual studio hosting whilst in compiled version??
    Tuesday, October 24, 2017 9:10 AM
  • But why the function invokes successfully under visual studio hosting whilst in compiled version??

    Hi stanley0000,

    Thank you for posting here.

    If you debug under visual studio hosting, it will improve debugger performance and enables new debugger features, such as partial-trust debugging and design-time expression evaluation. With this, you application will have more permission to get what you want.

    For more details, please refer to the following link.

    https://msdn.microsoft.com/en-us/library/ms242202.aspx

    https://msdn.microsoft.com/en-us/library/ms164730.aspx

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, October 25, 2017 9:11 AM
    Moderator
  • Hi,

    I found that when i move the core and UI component class from the original project to a new project and then reference the new project.

    The problems solved, the program can run without problem under hosted / not hosted environment.

    Regards,

    Stanley

    Wednesday, October 25, 2017 10:01 AM
  • Hi stanley0000,

    Thanks for your sharing. Please mark the solution as answer to close the thread. This will make answer searching easier in the forum and be beneficial to community members as well.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, November 1, 2017 1:55 AM
    Moderator