我应该如何导入Powerflex函数以用于C#?

时间:2012-03-22 04:36:49

标签: c# delphi pinvoke

我被赋予了在Visual Studio 2010 C#中使用 pfxlibn.dll 的任务,我从中可以看出它是一个Powerflex库。 http://pfxcorp.com/clib-fns.htm

我尝试了一些导入PclGetField功能的变体,例如:

[DllImport("pfxlibn.dll", SetLastError = true)]
public static extern void PclGetField(
    Int32 iHandle, 
    Int32 iFieldNum, 
    [MarshalAs(UnmanagedType.LPStr)] string Date
    ); 

[DllImport("pfxlibn.dll",
    CallingConvention = CallingConvention.StdCall,
    CharSet = CharSet.Ansi,
    EntryPoint = "PclGetField")]
public static extern int PclGetField(Int32 iHandle, Int32 iFieldNum, string Data)

[DllImport("pfxlibn.dll", EntryPoint = "PclGetField",
    ExactSpelling = true,
    CharSet = CharSet.Ansi,
    CallingConvention = CallingConvention.Cdecl)]
public static extern Int32 PclGetField(Int32 iHandle, Int32 iFieldNum,[MarshalAs(UnmanagedType.VBByRefStr)] ref string input);

到目前为止,以上都没有奏效。或以上的变化。

在Delphi中代码看起来像

pTmpBuf           : PChar;

iLastErr := PclGetField(fHandle,iField,pTmpBuf);

2 个答案:

答案 0 :(得分:8)

您链接的文档非常稀疏,所以要回答我们需要猜测的问题。

您需要的功能如下:

aResult PCLENTRY PclGetField (aDHandle fdh, anInt eno, aString data);
//Retrieves the formatted value of a field from a file buffer.

aResult PCLENTRY PclGetFieldLen (aDHandle fdh, anInt eno, anInt *length); 
//Gets the length of a field.

为了确定如何处理这个问题,我们需要更多信息:

  • PCLENTRY宏评估的内容是什么?我将假设__stdcall,但您需要检查您的头文件。
  • 什么是aResult?我将假设int,但您需要检查头文件。
  • 什么是aDHandle?我将假设void*INT_PTR,但您需要检查您的头文件。
  • 什么是anInt?我将假设int,但您需要检查头文件。
  • 使用了什么字符集? ANSI还是Unicode?我将假设ANSI。

您需要致电PclGetFieldLen以了解您需要多大的缓冲区。然后你将分配该缓冲区并调用PclGetField来填充它。您需要确定PclGetFieldLen返回的值是否包含零终止符。我假设它没有。

根据这些假设,您可以像这样编写pinvoke:

[DllImport("pfxlibn.dll", CallingConvention=CallingConvention.Stdcall)]
public static extern int PclGetFieldLen(fdh IntPtr, int eno, out int length); 

[DllImport("pfxlibn.dll", CallingConvention=CallingConvention.Stdcall,
    CharSet=CharSet.Ansi)]
public static extern int PclGetField(fdh IntPtr, int eno, StringBuilder data);

然后你可以调用这样的函数:

IntPtr fdh = .... // whatever function creates the database handle
int eno = .... // get the field number from somewhere
int length;
int res = PclGetFieldLen(fdh, eno, out length);
//check res for errors
StringBuilder data = new StringBuilder(length);
res = PclGetFieldLen(fdh, eno, data);
string field = data.ToString();

由于我们不了解所有细节,因此在这个答案中有许多未知数。您有头文件,您可以联系库供应商以解决未知问题。但希望上面的大纲告诉你需要回答哪些问题。

答案 1 :(得分:-1)

感谢David Heffernan,但是,我没有提供足够的信息或研究delphi代码。

缺少的主要项目是PclClear,PclPutField和PclFind。我后来发现了以下作品:

    [DllImport("pfxlibn.dll")]
    public static extern Int32 PclOpen(Int32 iHandle, String sName, Int32 iIndex);

    [DllImport("pfxlibn.dll")]
    public static extern Int32 PclClear(Int32 iHandle);

    [DllImport("pfxlibn.dll")]
    public static extern Int32 PclPutField(Int32 iHandle, Int32 iFieldNum, String sData);

    [DllImport("pfxlibn.dll")]
    public static extern Int32 PclFind(Int32 iHandle, Int32 iRelOp, Int32 iIndex);

    [DllImport("pfxlibn.dll")]
    public static extern Int32 PclGetFieldLen(Int32 iHandle, Int32 iField, out int length);



        error = CLib.PclOpen(_handle, path, 0);
        error = CLib.PclClear(_handle);
        error = CLib.PclPutField(_handle, 0, "10");  //searching for recnum 10
        error = CLib.PclFind(_handle, 1, 0);  // 0 = recnum index
        error = CLib.PclGetFieldLen(_handle, iField, out flenght);
        StringBuilder data = new StringBuilder(flenght);
        CLib.PclGetField(_handle, iField, data);

        if (error == 0)
        {
            return data.ToString();  
        }

我知道上面有一些垃圾错误,我很快就会修好。我只想回复并感谢大卫的帮助。此外,如果其他人使用pfxlibn.dll卡住了导出数据,他们可能会觉得这很有帮助。