Перенос NSModule для Mozilla в Delphi - PullRequest
2 голосов
/ 25 ноября 2010

В дополнение к этому вопросу, я думаю, я лучше покажу, что у меня есть.Я пытаюсь создать расширение для Firefox с Delphi, которое будет работать с будущими версиями Firefox, которые будут использовать экспортированную структуру NSModule, и больше не будет функцией NSGetModule.

Основные вопросы Iборюсь с на данный момент это:

  • Является ли код ниже правильный?Я могу ошибаться с тем, как работают указатели и массивы записей.
  • Как это отладить?Если я соберу его и он запустится, я уверен, что он будет работать, но при отладке моей библиотеки я могу только проверить, выполняет ли мой код инициализации свою работу.(и на данный момент Firefox 3.6, похоже, не принимает мой @mozilla.org/network/protocol;1?name=xxm контракт)

Код, который я пытаюсь перенести, находится здесь: http://mxr.mozilla.org/mozilla-central/source/xpcom/components/Module.h

type
  TConstructorProcPtr=function(aOuter:nsISupports;const aIID:TGUID;var aResult:pointer):nsresult;
  TLoadFuncPrt=function:nsresult;
  TUnloadFuncPrt=procedure;
  TCIDEntry=record
    cid:TGUID;
    service:boolean;
    getFactoryProc:pointer;//TGetFactoryProcPtr;
    constructorProc:TConstructorProcPtr;
  end;
  TContractIDEntry=record
    contractid:PChar;
    cid:TGUID;//PGUID?
  end;
  TCategoryEntry=record
    category,entry,value:PChar;
  end;

  TXPCOMModule=packed record
    kVersion:integer;//=1;
    mVersion:cardinal;//kModuleVersion
    mCIDs:^TCIDEntry;//pointer to first in array, last should be nil
    mContractIDs:^TContractIDEntry;//pointer to first in array, last should be nil
    mCategoryEntries:^TCategoryEntry;//pointer to first in array, last should be nil
    getFactoryProcPtr:pointer;//TGetFactoryProcPtr;
    loadProc:TLoadFuncPrt;
    unloadProd:TUnloadFuncPrt;
  end;

1 Ответ

1 голос
/ 26 ноября 2010

Вам почти наверняка понадобится cdecl соглашение о вызовах для всех ваших объявлений процедур и указателей на функции:

TConstructorProcPtr = function(aOuter: nsISupports; const aIID: TGUID; var aResult: Pointer): nsresult; cdecl;
TLoadFuncPrt = function: nsresult; cdecl;
TUnloadFuncPrt = procedure; cdecl;

Я предполагаю, что вы объявили nsISupports как интерфейс Delphi. В противном случае необходимо убедиться, что указанный выше параметр aOuter является указателем, как в коде C ++.

Для TContractIDEntry и всех других мест, где вы используете PChar, я советую вам использовать PAnsiChar вместо этого. Размер типа Char в Delphi изменился пару лет назад, но C ++ char всегда есть и будет одним байтом, поэтому явно используйте однобайтовый тип символов Delphi. Кроме того, ваш комментарий задается вопросом, было ли правильно объявить поле cid как PGUID; звездочка означает указатель.

TContractIDEntry = record
  contractid: PAnsiChar;
  cid: PGUID;
end;

Поле kVersion не должно быть членом записи, которую вы объявляете. В C ++ это static член, что означает, что он не занимает места в самой структуре; он используется всеми экземплярами этого типа. Это эквивалентно полю класса в классе Delphi, но я не думаю, что записи предлагают такую ​​возможность. Сделайте это переменной уровня блока вместо поля.

...