简体   繁体   中英

How should I import Powerflex functions for use in C#?

I have been given the task of using pfxlibn.dll in Visual Studio 2010 C#, which from what I can make out is a Powerflex library. http://pfxcorp.com/clib-fns.htm

I have tried a few variations of importing the PclGetField function, for example:

[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);

So far, none of the above have worked. Or variations of the above.

Within Delphi the code looks like

pTmpBuf           : PChar;

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

The documentation you link to is very sparse so to answer the question we need to guess somewhat.

The functions you need are these:

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.

In order to know for sure how to handle this we need more information:

  • What does the PCLENTRY macro evaluate to? I'm going to assume __stdcall , but you will need to check your header file.
  • What is aResult ? I'm going to assume int but you will need to check your header file.
  • What is aDHandle ? I'm going to assume void* or INT_PTR but you will need to check your header file.
  • What is anInt ? I'm going to assume int but you will need to check your header file.
  • What character set is used? ANSI or Unicode? I'm going to assume ANSI.

You are going to need to call PclGetFieldLen to find out how big a buffer you need. And then you will allocate that buffer and call PclGetField to populate it. You will need to find out whether or not the value returned by PclGetFieldLen includes the zero-terminator or not. I'm assuming that it does not.

With these assumptions you would write the pinvoke like this:

[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);

You can then call the functions like this:

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();

Since we don't know all the details, there are a bunch of unknowns in this answer. You have the header file, and you can contact the library vendor to resolve the unknowns. But hopefully the outline above tells you what questions need to be answered.

Thanks David Heffernan, However, i did not give enough information or research the delphi code enough.

The main items that were missing was PclClear, PclPutField and PclFind. I have since found the following works:

    [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();  
        }

I know the above has crap error catching which i will be fixing up shortly. I just want to reply and thank David for his help. Plus if anyone else is stuck with export data using pfxlibn.dll they might find this helpful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM