Как мне импортировать функции Powerflex для использования в C #? - PullRequest
0 голосов
/ 22 марта 2012

Мне было дано задание использовать pfxlibn.dll в Visual Studio 2010 C #, из чего я могу выделить библиотеку 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 ]

8 голосов
/ 22 марта 2012

Документация, на которую вы ссылаетесь, очень скудна, поэтому для ответа на вопрос нам нужно немного угадать.

Вам нужны следующие функции:

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, нулевой терминатор или нет. Я предполагаю, что это не так.

С этими допущениями вы бы написали пинвоук так:

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

Поскольку мы не знаем всех деталей, в этом ответе есть куча неизвестных. У вас есть файл заголовка, и вы можете обратиться к поставщику библиотеки для разрешения неизвестных. Но, надеюсь, приведенный выше план говорит вам, на какие вопросы нужно ответить.

0 голосов
/ 23 марта 2012

Спасибо, Дэвид Хеффернан, однако, я не дал достаточно информации или недостаточно изучил код 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, они могут найти это полезным.

...