[Delphi]View PlainCopy
- Function ABC (A:integer): IUnknown;
This is a Delphi function declaration, it looks very simple, only one parameter, but the real situation? After being translated into binary code, there are actually 2 parameters for the function!
In order to explain the problem in more detail, first use Delphi to write a DLL, export an interface, the interface has a show method.
[Delphi]View PlainCopy
- Library Project1;
- Uses
- Windows;
- {$R *.res}
- Type
- ITest = Interface
- procedure Show (); stdcall;
- end;
- TTest = Class (Tinterfacedobject, ITest)
- Public
- procedure Show (); stdcall;
- end;
- function gettest:itest; stdcall;
- Begin
- Result: = TTest. Create;
- End
- Exports
- Gettest;
- {TTest}
- Procedure TTest. Show;
- Begin
- OutputDebugString (' Hello World ');
- End
- Begin
- End.
Callers are written in C + +
[CPP]View PlainCopy
- #include "stdafx.h"
- #include <iostream>
- #include <Windows.h>
- Interface ITest: public IUnknown
- {
- virtual void __stdcall Show () = 0;
- };
- typedef itest* (WINAPI *getitest) ();
- int _tmain (int argc, _tchar* argv[])
- {
- hmodule h = LoadLibrary (TEXT ("Project1.dll"));
- if (h! = 0)
- {
- Getitest get = (getitest) GetProcAddress (H, "gettest");
- ITest *test = Get ();
- Test->show ();
- Test->release ();
- }
- System ("pause");
- return 0;
- }
Directly eject a memory error after running
The error statement is in the DLL
[Delphi]View PlainCopy
- function gettest:itest; stdcall;
- Begin
- Result: = TTest. Create;
- End
You can see the problem by looking at the function in the form of disassembly code.
As you can see, when the function return value is an interface type, the return value is actually an implicit parameter and is a level two pointer type. The use of Dephi does not find the problem because it is automatically optimized.
In multi-language mixed programming, there is an empty memory error when you return an interface or an object directly.
The modified calling code
[CPP]View PlainCopy
- #include "stdafx.h"
- #include <iostream>
- #include <Windows.h>
- Interface ITest: public IUnknown
- {
- virtual void __stdcall Show () = 0;
- };
- The correct function prototype
- typedef VOID (WINAPI *getitest) (itest**);
- int _tmain (int argc, _tchar* argv[])
- {
- hmodule h = LoadLibrary (TEXT ("Project1.dll"));
- if (h! = 0)
- {
- Getitest get = (getitest) GetProcAddress (H, "gettest");
- //Modified call method
- ITest *test = nullptr;
- Get (&test);
- Test->show ();
- Test->release ();
- }
- System ("pause");
- return 0;
- }
Finally, a little experience can be summed up, when the Delphi function return value is the interface type, the function will consider the first parameter is an interface buffer, used to accept the interface instance object.
Is it possible to return an interface pointer directly without changing the way the C + + side calls? The answer is yes, as long as you change the return data type to the underlying type
[Delphi]View PlainCopy
- function Gettest:pointer; stdcall;
- Var
- Temp:itest;
- Begin
- Temp: = TTest. Create;
- Temp. _addref;
- Result: = Pointer (Temp);
- End
Since the function return value is no longer an interface type, Delphi does not invoke the AddRef method of the interface to call the reference count + 1, so the AddRef method must be called manually after the interface is created.
Otherwise, the function will automatically release temp after the end, causing the return value to be a wild pointer.
http://blog.csdn.net/aqtata/article/details/19079737
Traps in the interface type when mixing calls