Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you're not sure what you're doing, always start with the most <em>literal</em> translation. The function prototype says it receives a pointer to a pointer to a char, so that's what you should use:</p> <pre><code>type PTR_Allocate = procedure(param1: ^^Char; param2: ^LongWord); cdecl; </code></pre> <p>Once you're sure it's right, <em>then</em> start replacing things with their more Delphi-like equivalents. If you skip this first step, you might never get it right because you'll just keep making changes to something that started out wrong.</p> <p>So, are you sure the above is right? Not quite. <code>Char</code> in Delphi can have different meanings depending on the product version. You're using Delphi 7, but you might upgrade, so you might share this code with someone else, so you should be explicit about what size Char you want. Use AnsiChar when you need a one-byte type.</p> <pre><code>type PTR_Allocate = procedure(param1: ^^AnsiChar; param2: ^LongWord); cdecl; </code></pre> <p>Now we can start making it look more like Delphi. One level of pointer parameter can be replaced with a "var" or "out" directive. Do that to each parameter:</p> <pre><code>type PTR_Allocate = procedure(out param1: ^AnsiChar; var param2: LongWord); cdecl; </code></pre> <p>Pointer-to-AnsiChar is such a common type that Delphi already has a name for it: PAnsiChar. Use the idiomatic name:</p> <pre><code>type PTR_Allocate = procedure(out param1: PAnsiChar; var param2: LongWord); cdecl; </code></pre> <p>And finally, you might wish to take some liberty with the whole notion that there are characters involved at all. You're clearly allocating memory for arbitrary byte buffers, so Byte is probably a better choice than any character type. Recent Delphi versions declare a pointer-to-byte type, so use that:</p> <pre><code>type PTR_Allocate = procedure(out param1: PByte; var param2: LongWord); cdecl; </code></pre> <hr> <p>Now on to <code>SetAllocateFunction</code>. It says it receives a <code>PTR_Allocate</code> parameter, which is a pointer to a function. Delphi's procedure types are implicitly pointers, so the type we've declared above is already exactly right for the Delphi equivalent. Don't pass it by reference with an extra "var" directive or you will have the problems you've seen, even before your program attempts to allocate any memory. This is something the other answers have overlooked.</p> <pre><code>procedure SetAllocateFunction(param: PTR_Allocate); cdecl; </code></pre> <p>Don't add an underscore to the start of the name, either, unless you <em>want</em> to make it inconvenient to call in your own code. If it's exported from the DLL using a different name, then use a "name" clause when you write the function's implementation:</p> <pre><code>procedure SetAllocateFunction; extern 'foo.dll' name '_SetAllocateFunction'; </code></pre> <hr> <p>Finally, how to implement the allocation function. Start with something that matches the signature for PTR_Allocate, and then go ahead and implement it using as literal a translation as possible from the original C++ code.</p> <pre><code>procedure Allocate(out pbuffer: PByte; var psize: LongWord; cdecl; begin psize := psize * 2; GetMem(pbuffer, psize); end; </code></pre> <p>You can set it with the function from before:</p> <pre><code>SetAllocateFunction(Allocate); </code></pre> <p>Notice I didn't need a separate variable and I haven't used the <code>@</code> operator. If you need to use the <code>@</code> operator to mention a function pointer, in <em>most</em> cases, you're doing it wrong. You usually don't need it. Using that operator can <em>hide</em> errors in your program, such as signature mismatches, because the default setting is for the <code>@</code> operator to be <em>untyped</em>. Using it removes the type from the function pointer, and untyped pointers are compatible with everything in Delphi, so they fit with any other function-pointer type, including the ones with wrong signatures.</p> <p>Only use <code>@</code> on a function pointer when the compiler has already indicated that it has tried to <em>call</em> the function, such as by mentioning how you don't have enough parameters or by mentioning the function's return type.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload