关于C#调用带有回调参数的API
这几天使用C#调用PB API来分析pb的源代码文件,(在此严重鄙视PB,人家的源码都是文本,就你的非要自己捣鼓),其中一个API原型是这样的
int PBORCA_LibraryDirectory ( HPBORCA hORCASession, LPSTR lpszLibName, LPSTR lpszLibComments, int iCmntsBuffSize, PBORCA_LISTPROC pListProc, LPVOID pUserData );
参数说明
hORCASession
Handle to previously established ORCA session
lpszLibName
Pointer to a string whose value is the filename of the library for which you want directory information
lpszLibComments
Pointer to a buffer in which ORCA will put comments stored with the library
iCmntsBuffSize
Size of the buffer pointed to by lpszLibComments
pListProc
Pointer to the PBORCA_LibraryDirectory callback function. The callback function is called for each entry in the library
The information ORCA passes to the callback function is entry name, comments, size of entry, and modification time, stored in a structure of type PBORCA_DIRENTRY
pUserData
Pointer to user data to be passed to the PBORCA_LibraryDirectory callback function
The user data typically includes the buffer or a pointer to the buffer in which the callback function formats the directory information as well as information about the size of the buffer
其中pListProc作为回调函数,定义如下
typedef void (FAR PASCAL *PBORCA_LISTPROC) ( PPBORCA_DIRENTRY, LPVOID );
参数说明
PPBORCA_DIRENTRY
Pointer to the structure PBORCA_DIRENTRY, described next
LPVOID
Long pointer to user data
结构体PBORCA_DIRENTRY structure如下
typedef struct pborca_direntry
{
CHAR szComments[PBORCA_MAXCOMMENT + 1];
LONG lCreateTime;
LONG lEntrySize;
LPSTR lpszEntryName;
PBORCA_TYPE otEntryType;}
PBORCA_DIRENTRY, FAR *PPBORCA_DIRENTRY;
以上的详细参考资料在
http://manuals.sybase.com/onlinebooks/group-pb/adt0650e/orca/@Generic__BookTextView/7001;pt=4344;lang=zh#X
[解决办法]
C\C++ 中的 char是类型一个字节
C# 中的 char类型,所以转换的时候要用byte取代C\C++中的char
大概是这样:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = PBORCA_MAXCOMMENT + 1)]
public byte[] szComments; // Buffer for entry info
参考EnumWindows标准API回调的使用:
using System.Runtime.InteropServices;public delegate bool WNDENUMPROC(IntPtr hwnd, int lParam);[DllImport("user32.dll")]public static extern int EnumWindows(WNDENUMPROC lpEnumFunc, int lParam);public static bool EnumFunc(IntPtr hwnd, int lParam){ Console.WriteLine("Window handle is " + hwnd); return true;}private void button1_Click(object sender, EventArgs e){ EnumWindows(EnumFunc, 0);}
[解决办法]
int PBORCA_LibraryDirectory ( HPBORCA hORCASession, LPSTR lpszLibName, LPSTR lpszLibComments, int iCmntsBuffSize, PBORCA_LISTPROC pListProc, LPVOID pUserData );
从函数原型的字面意思很难猜出 LPSTR lpszLibName, LPSTR lpszLibComments
这两个是传入还是传出了
传入用 string就可以了
传出用 StringBuilder
PBORCA_DIRENTRY这个结构里面的 LPSTR lpszEntryName;
这个可能会有点麻烦,这个应该是传出一个字符串
如果文档中没有定义的话,那这个应该是传出一个指针
你可以尝试定义为 IntPtr,然后用
Marshal.PtrToStringAnsi
或者 PtrToStringAuto 或者 PtrToStringBSTR 或者 PtrToStringUni 转换一下