2

In extension to this question, I guess I'll best show what I've got so far. What I'm trying to do is create a Firefox extension with Delphi, that'll work with the Firefox versions of the future that will use an exported NSModule structure, and no longer an NSGetModule function.

Main questions I'm struggling with for the moment is:

  • Is the code below correct? I may be wrong with how the pointers and arrays of records work.
  • How to debug this? If I build it and it runs then I'm kind of sure it'll work, but in debugging my library I can only check if my init code does its job. (and for now, Firefox 3.6 doesn't seem to pick up my @mozilla.org/network/protocol;1?name=xxm contract)

The code I'm trying to port is here: 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;
Community
  • 1
  • 1
Stijn Sanders
  • 35,982
  • 11
  • 45
  • 67
  • 1
    I have no idea what your second question is about. As you know, Stack Overflow works best when you only ask one question at a time. Could you please clarify how your debugging question is more related to your C++ translation question? – Rob Kennedy Nov 26 '10 at 08:25
  • The two questions are very closely related. I put up some exported data from my project, but I assume there's Firefox code that consumes this code, and I assume I could theoretically step through FireFox while it is using my NSModule data. Thing is I have no clue how to set up an environment that can load the firefox source, and run a debugger with it. (I grew up with Delphi, there it's a package deal) – Stijn Sanders Nov 26 '10 at 19:13

1 Answers1

1

You almost certainly need the cdecl calling convention on all your procedure- and function-pointer declarations:

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

I assume you've declared nsISupports as a Delphi interface. Otherwise, you need to make sure the aOuter parameter above is a pointer as it is in the C++ code.

For TContractIDEntry, and all the other places where you use PChar, I advise you to use PAnsiChar instead. The size of Delphi's Char type changed a couple of years ago, but the C++ char is and always will be one byte, so use Delphi's one-byte character type explicitly. Also, your comment wondering whether to declare the cid field as a PGUID was correct; asterisk means pointer.

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

The kVersion field should not be a member of the record you declare. In C++, it's a static member, which means it occupies no space in the structure itself; it's shared by all instances of that type. It's equivalent to a class field in a Delphi class, but I don't think records offer that feature. Make it a unit-level variable instead of a field.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • 2
    I keep forgetting to mention how I get to use nsISupports in Delphi, thanks to someone (that doesn't answer my calls), you can just map the 'basic' IInterface methods over the nsISupports methods: http://d-gecko.svn.sourceforge.net/viewvc/d-gecko/trunk/GeckoSDK/nsXPCOM.pas?revision=10&view=markup#l1095 – Stijn Sanders Nov 26 '10 at 19:20