C# 更正来自 C++ 的托管代码

Posted

技术标签:

【中文标题】C# 更正来自 C++ 的托管代码【英文标题】:C# Correct managed code from C++ 【发布时间】:2011-07-27 11:21:45 【问题描述】:

我必须在我的 C# 应用程序中使用这个外部函数“GetOpenedFiles”(更多信息:http://www.codeproject.com/KB/shell/OpenedFileFinder.aspx)。 我不知道,因为我可以编写这个函数的包装器:

void GetOpenedFiles(LPCWSTR lpPath, OF_TYPE Filter, OF_CALLBACK CallBackProc, UINT_PTR pUserContext);

原始 C++ 代码 (OpenFilefinder.h)

enum OF_TYPE

    FILES_ONLY = 1,
    MODULES_ONLY = 2,
    ALL_TYPES = 3
;

struct OF_INFO_t

    DWORD dwPID;
    LPCWSTR lpFile;
    HANDLE hFile;
;

typedef void (CALLBACK* OF_CALLBACK)(OF_INFO_t OpenedFileInf0, UINT_PTR uUserContext );


extern "C" __declspec(dllexport) void ShowOpenedFiles( LPCWSTR lpPath );
extern "C" __declspec(dllexport) void GetOpenedFiles( LPCWSTR lpPath, 
                                                      OF_TYPE Filter,
                                                      OF_CALLBACK CallBackProc,
                                                      UINT_PTR pUserContext );

我的 C# 应用程序:

    public enum OF_TYPE : int
    
        FILES_ONLY = 1,
        MODULES_ONLY = 2,
        ALL_TYPES = 3
    

    public struct OF_INFO_t
    
        ?????? dwPID;
        ?????? lpFile;
        ?????? hFile;
    

    [DllImport("OpenFileFinder.dll", EntryPoint = "GetOpenedFiles")]
    static extern void GetOpenedFiles(??????? lpPath, OF_TYPE filter, ????? CallBackProc, ????? pUserContext);

如何在我的 C# 应用程序中正确使用此 dll 函数?

编辑:

这是我最新的sn-p,但从不调用回调函数:

namespace Open64

    class Program
    

        public Program()
        
            GetOpenedFiles("C:\\", OF_TYPE.ALL_TYPES, CallbackFunction, UIntPtr.Zero);
        

        //void GetOpenedFiles(LPCWSTR lpPath, OF_TYPE Filter, OF_CALLBACK CallBackProc, UINT_PTR pUserContext);

        public enum OF_TYPE : int
        
            FILES_ONLY = 1,
            MODULES_ONLY = 2,
            ALL_TYPES = 3
        

        public struct OF_INFO_t
        
            Int32 dwPID;
            String lpFile;
            IntPtr hFile;
        

        public delegate void CallbackFunctionDef(OF_INFO_t info, IntPtr context);

        [DllImport("OpenFileFinder.dll", EntryPoint = "GetOpenedFiles")]
        static extern void GetOpenedFiles(string lpPath, OF_TYPE filter, CallbackFunctionDef CallBackProc, UIntPtr pUserContext);

        public void CallbackFunction(OF_INFO_t info, IntPtr context)
        
            Console.WriteLine("asd");
        

        [STAThread]
        static void Main()
        
            new Program();
        
    


【问题讨论】:

【参考方案1】:

这就是你将如何编组以下类型:

DWORD => Int32
LPCWSTR => String
HANDLE => IntPtr
UINT_PTR => UIntPtr

【讨论】:

【参考方案2】:
public struct OF_INFO_t

   Int32 dwPID;
   String lpFile;
   IntPtr hFile;


public delegate void CallbackFunctionDef(OF_INFO_t info, UIntPtr context);

[DllImport("OpenFileFinder.dll", EntryPoint = "GetOpenedFiles")]
static extern void GetOpenedFiles(string lpPath, OF_TYPE filter, CallbackFunctionDef CallBackProc, UIntPtr pUserContext);

编辑:这是完整的程序

class Program

    public Program()
    
        GetOpenedFiles("C:\\", OF_TYPE.ALL_TYPES, CallbackFunction, UIntPtr.Zero);
        Console.ReadKey();
    

    //void GetOpenedFiles(LPCWSTR lpPath, OF_TYPE Filter, OF_CALLBACK CallBackProc, UINT_PTR pUserContext);

    public enum OF_TYPE : int
    
        FILES_ONLY = 1,
        MODULES_ONLY = 2,
        ALL_TYPES = 3
    

    [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Unicode)]
    public struct OF_INFO_t
    
        public Int32 dwPID;
        public String lpFile;
        public IntPtr hFile;
    

    public delegate void CallbackFunctionDef(OF_INFO_t info, IntPtr context);

    [DllImport("OpenFileFinder.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "GetOpenedFiles")]
    static extern void GetOpenedFiles(string lpPath, OF_TYPE filter, CallbackFunctionDef CallBackProc, UIntPtr pUserContext);

    public void CallbackFunction(OF_INFO_t info, IntPtr context)
    
        //List the files
        Console.WriteLine(info.lpFile);
    

    [STAThread]
    static void Main()
    
        new Program();
    

【讨论】:

我认为您的意思是 delegate 中的 IntPtr 根据原始代码是 UIntPtr,并且可能在代码末尾有一个右括号和分号。 :) +1 虽然 感谢您的回复。如何将 CallbackFunctionDef 声明为我的回调函数? 任何具有相同签名的方法都应该这样做。例如:void SomeCallback(OF_INFO_t info, UIntPtr context) /*code here*/ 完美编译但不调用 MyCallback 函数。我用我的代码编辑我的问题 现在我编辑我的未决问题。此代码从不调用我的回调函数。

以上是关于C# 更正来自 C++ 的托管代码的主要内容,如果未能解决你的问题,请参考以下文章

我想从 C++ 非托管代码调用 C# 委托。无参数委托工作正常,但有参数委托使我的程序崩溃

如何在托管 (C#) 和非托管 (C++) 代码之间来回传递数组内容

使用来自 C# 的托管 C++ dll

从托管 C# 代码调用非托管 C++ 代码以生成脱机域加入 blob

如何在托管代码(C#)中从本机代码(C++)获取字符串数组

非托管 C++ 代码向托管代码发送字符串的错误