Портирование NSModule от Mozilla на Delphi

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

Основные вопросы, с которыми я борюсь на данный момент:

  • Верен ли приведенный ниже код? Я могу ошибаться в том, как работают указатели и массивы записей.
  • Как это отладить? Если я соберу его и он запустится, я почти уверен, что он будет работать, но при отладке моей библиотеки я могу только проверить, выполняет ли мой код инициализации свою работу. (и на данный момент 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;

person Stijn Sanders    schedule 25.11.2010    source источник
comment
Я понятия не имею, о чем ваш второй вопрос. Как вы знаете, Stack Overflow работает лучше всего, когда вы задаете только один вопрос за раз. Не могли бы вы уточнить, как ваш вопрос об отладке больше связан с вашим вопросом перевода на С++?   -  person Rob Kennedy    schedule 26.11.2010
comment
Эти два вопроса очень тесно связаны. Я поместил некоторые экспортированные данные из своего проекта, но я предполагаю, что есть код Firefox, который использует этот код, и я предполагаю, что теоретически могу пройти через FireFox, пока он использует мои данные NSModule. Дело в том, что я понятия не имею, как настроить среду, которая может загрузить исходный код Firefox и запустить с ним отладчик. (Я вырос с Delphi, там все в пакете)   -  person Stijn Sanders    schedule 26.11.2010


Ответы (1)


Вам почти наверняка понадобится соглашение о вызовах 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. Размер типа Delphi Char изменился пару лет назад, но C++ char всегда был и будет одним байтом, поэтому явно используйте однобайтовый символьный тип Delphi. Кроме того, ваш комментарий задавался вопросом, правильно ли объявлять поле cid как PGUID; звездочка означает указатель.

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

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

person Rob Kennedy    schedule 26.11.2010
comment
Я постоянно забываю упомянуть, как я использую nsISupports в Delphi, благодаря кому-то (который не отвечает на мои звонки), вы можете просто сопоставить «базовые» методы IInterface с методами nsISupports: d-gecko.svn.sourceforge.net/ viewvc/d-gecko/trunk/GeckoSDK/ - person Stijn Sanders; 26.11.2010