View Issue Details

IDProjectCategoryView StatusLast Update
0002396ScribusInternalpublic2011-06-10 23:05
ReporterringercAssigned Tojghali  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platformx86 LinuxOSFedora CoreOS Version3
Product Version1.3.1cvs 
Summary0002396: Correct cross-DLL memory handling on win32
DescriptionFor Jean Ghali's win32 port, it'd help to have some careful handling of memory. Win32 requires one to be very fussy, because:

(a) It has weird segmented-memory issues with DLLs; and
(b) win32 users expect to be able to dynamically link to C and C++ DLLs built with different compilers, against different C runtimes, but win32 provides no strict C++ ABI to facilitate doing this safely.

This leads to rules like needing to create and destroy an object in the module its class is defined in, or face crashes / memory leaks.

It's also possible to link 32 bit and 64 bit code under win32. This means that pointers to memory above the 2GB (?) memory boundary are invalid when passed to 32 bit code. God knows how to handle that one...
Additional InformationRequirements appear to include:

  - Factory functions and destroy() methods on objects that are to be used
    across segment bounaries.
  - Possible overloading of `new' and `delete' to prevent incorrect use, or
    to call the correct functions. I have an article on this somewhere that
    I need to find...
TagsNo tags attached.
Patch

Relationships

related to 0002097 closedringerc Re-write plugin API 
related to 0002398 closedjghali Get plugins to compile on Windows (win32) 
related to 0002463 closedjghali Issues with win32 build 

Activities

ringerc

2005-08-08 07:51

reporter   ~0005927

Reminder sent to: jghali

Adding you to the monitor list on this one.

I've broken this bug out from the plugin API stuff. I think it's important to get the plugin API in place sooner rather than later, and it looks like the win32 memory handling can be addressed in a later refinement of it if required.

Please correct me if I'm wrong.

2005-08-08 07:59

 

cppcompat.html (23,170 bytes)   
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><!-- base href="http://aegisknight.org/cppinterface.html" --><title>Binary-compatible C++ Interfaces</title><style type="text/css">
body {
  background-color: #FFFFFF;
}
pre {
  background-color: #d0d0d0;
}
code {
  background-color: #d0d0d0;
}
</style></head>
<body><table border="1" width="100%"><tbody><tr><td><table color="#ffffff" bgcolor="#ffffff" border="1" cellpadding="10" cellspacing="0" width="100%"><tbody><tr><td><font color="black" face="arial,sans-serif" size="-1">This is <b><font color="#0039b6">G</font> <font color="#c41200">o</font> <font color="#f3c518">o</font> <font color="#0039b6">g</font> <font color="#30a72f">l</font> <font color="#c41200">e</font></b>'s <a href="http://www.google.com/help/features.html#cached"><font color="blue">cache</font></a> of <a href="http://aegisknight.org/cppinterface.html"><font color="blue">http://aegisknight.org/cppinterface.html</font></a> as retrieved on 19 Jul 2005 00:09:53 GMT.<br>
<b><font color="#0039b6">G</font> <font color="#c41200">o</font> <font color="#f3c518">o</font> <font color="#0039b6">g</font> <font color="#30a72f">l</font> <font color="#c41200">e</font></b>'s cache is the snapshot that we took of the page as we crawled the web.<br>
The page may have changed since that time.  Click here for the <a href="http://aegisknight.org/cppinterface.html"><font color="blue">current page</font></a> without highlighting.<br>
This cached page may reference images which are no longer available. Click here for the <a href="http://64.233.167.104/search?q=cache:OpN8L_LD7qgJ:aegisknight.org/cppinterface.html+windows+or+win32+qt++dll+memory+factory&amp;hl=en&amp;hs=vVM&amp;lr=&amp;client=firefox-a&amp;strip=1"><font color="blue">cached text</font></a> only.<br>To link to or bookmark this page, use the following url: <code>http://www.google.com/search?q=cache:OpN8L_LD7qgJ:aegisknight.org/cppinterface.html+windows+or+win32+qt++dll+memory+factory&amp;hl=en&amp;client=firefox-a</code></font><br><br><center><font size="-2"><i>Google is not affiliated with the authors of this page nor responsible for its content.</i></font></center></td></tr>
<tr><td>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><font color="black" face="arial,sans-serif" size="-1">These search terms have been highlighted:&nbsp;</font></td><td bgcolor="#ffff66"><b><font color="black" face="arial,sans-serif" size="-1">windows&nbsp;</font></b></td><td bgcolor="#a0ffff"><b><font color="black" face="arial,sans-serif" size="-1">win32&nbsp;</font></b></td><td bgcolor="#99ff99"><b><font color="black" face="arial,sans-serif" size="-1">qt&nbsp;</font></b></td><td bgcolor="#ff9999"><b><font color="black" face="arial,sans-serif" size="-1">dll&nbsp;</font></b></td><td bgcolor="#ff66ff"><b><font color="black" face="arial,sans-serif" size="-1">memory&nbsp;</font></b></td><td bgcolor="#880000"><b><font color="white" face="arial,sans-serif" size="-1">factory&nbsp;</font></b></td></tr></tbody></table>
</td></tr></tbody></table></td></tr></tbody></table>
<hr>








<h3>Binary-compatible C++ Interfaces</h3>
<h3>Chad Austin, 2002.02.15</h3>

<hr>

<h4>Updates</h4>

<h5>2003.02.21</h5>

<p>
Clarified some of my comments thanks to feedback and suggestions from
Razvan Surdulescu.  For actual COM compatibility, I added __stdcall to
the method declarations as well.  (Apparently, if you follow the
guidelines of this article, it's easy to add bindings from your <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> to
Delphi and VB!)
</p>

<h5>2002.04.03</h5>

<p>
Somebody (unfortunately, I lost his e-mail address and name before I
could write it down.  if you're reading this or you know who sent it,
please drop me a line) sent me another guideline.  The gist of it is
that you shouldn't use overloaded methods in your interfaces.
Different compilers will order them in the vtable differently.
</p>

<h5>2002.03.27</h5>

<p>
Ben Scott (bscott at iastate dot edu) submitted some excellent classes
that simplify usage of the concepts presented in this article.  Simply
derive your interface classes from DLLInterface and your
implementations from DLLImpl<interfacet>!  Download the source file <a href="http://aegisknight.org/dllinterface.h">here</a>.
</interfacet></p>

<hr>

<h4>Overview</h4>

<p>
This article explains how to create C++ <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> APIs that will work across several
compilers and configuration settings (Release, Debug, etc.).
</p>

<h4>Background</h4>

<p>
Many platforms have an
<acronym title="Application Binary Interface">ABI</acronym> for their preferred
programming language.  For example, BeOS's primary language is C++, so the C++
compiler must be able to generate code that remains binary compatible with the
operating system's C++ system calls (and classes, etc.).
</p>

<p>
The <b style="color: black; background-color: rgb(255, 255, 102);">Windows</b> <acronym title="Application Program Interface">API</acronym> and
ABI were defined for C, so C++ compiler writers had free reign to implement the
C++ ABI however they felt.  Eventually, however, Microsoft created an
object-oriented ABI for <b style="color: black; background-color: rgb(255, 255, 102);">Windows</b> called COM.  To simplify COM usage, they made
the vtables of their C++ ABI match the vtables required in COM interface.
Since a <b style="color: black; background-color: rgb(255, 255, 102);">Windows</b> compiler that can't use COM is pretty limited, other compiler
vendors enforced the mapping between COM vtables and C++ vtables.
</p>

<p>
There are several aspects to an ABI.  This article only discusses the issues
with using C++ in <b style="color: black; background-color: rgb(255, 255, 102);">Windows</b>.  Other platforms have different requirements.
(Fortunately, since most other platforms aren't as popular as <b style="color: black; background-color: rgb(255, 255, 102);">Windows</b>, they
have only one or two compilers, and thus there isn't much of a problem.)
</p>

<h4>Concepts</h4>

<ul>
<li><strong>ABI</strong> -
  Application Binary Interface.
  The binary interface between systems.  If a binary interface changes, both
  sides of the interface (the user and the implementation) must be recompiled.
</li>
<li><strong>API</strong> -
  Application Program Interface.
  The source interface between systems.  If a source interface changes, code
  that uses that interface must be modified.  API changes usually imply ABI
  changes.
</li>
<li><strong>Interface</strong> -
  A class where every method is pure virtual, and thus has no inherent
  implementation.  An interface is merely a protocol for communication between
  objects.
</li>
<li><strong><b style="color: white; background-color: rgb(136, 0, 0);">Factory</b></strong> -
  Something that creates objects.  In this article, we'll use a single global
  function as our <b style="color: white; background-color: rgb(136, 0, 0);">factory</b>.
</li>
<li><strong><b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> Boundary</strong> - The line between code instantiated
  in a <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> and code in a calling process is called the <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> boundary.
  In some cases, code can be on both sides of the boundary: Consider
  an inline function in a header file that gets used in the <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> and
  the executable.  The function is actually instantiated on both sides
  of the boundary.  Therefore, if the inline function has a static
  variable, two variables will be created, one in the executable and
  one in the <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b>, and which is used depends on whether the code in the
  <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> or the executable is calling the function.
</li>
</ul>

<h4>Initial Attempt</h4>

<p>
Let's say you want to create a portable windowing API and you want to stick
the implementation in a <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b>.  I'm going to create a class called Window
which can represent a window in several different windowing systems: <b style="color: black; background-color: rgb(160, 255, 255);">Win32</b>,
MFC, wxWindows, <b style="color: black; background-color: rgb(153, 255, 153);">Qt</b>, Gtk, Aqua, X11, Swing (*gasp*), etc...  We'll walk through
several attempts at creating an interface until it works across different
implementations, compilers, and compiler settings.
</p>

<pre>// Window.h

#include &lt;string&gt;

#ifdef <b style="color: black; background-color: rgb(160, 255, 255);">WIN32</b>
  #ifdef EXPORTING
    #define DLLIMPORT __declspec(dllexport)
  #else
    #define DLLIMPORT __declspec(dllimport)
  #endif
  #define CALL __stdcall
#else
  #define DLLIMPORT
  #define CALL
#endif

class DLLIMPORT Window {
public:
  Window(std::string title);
  ~Window();

  void setTitle(std::string title);
  std::string getTitle();

  // ...

private:
  HWND m_window;
};
</pre>

<p>
I'm not going to show the implementation, as I'm assuming you already know how
to do that.  There is one glaring problem with this interface:  It assumes
you're using the basic <b style="color: black; background-color: rgb(160, 255, 255);">Win32</b> API.  That is, it holds an HWND as a
private member, which introduces a dependency between our Window class
and the <b style="color: black; background-color: rgb(160, 255, 255);">Win32</b> SDK.  One possible solution is to use the pImpl idiom to
remove the class's private members from the class definition.
You can read more about that elsewhere 
<a href="http://www.gotw.ca/publications/mill04.htm">[1]</a>,
<a href="http://www.gotw.ca/publications/mill05.htm">[2]</a>, 
<a href="http://www.gotw.ca/gotw/028.htm">[3]</a>, and
<a href="http://c2.com/cgi/wiki?PimplIdiom">[4]</a>.
Also, you cannot add new members to the
class without breaking binary compatibility, as the size of the class
changes.</p>

<p>
Perhaps the most important problem with this approach is
that the methods are non-virtual.  Thus, they are implemented as
specially named functions that take the 'this' pointer as their first
argument.  Unfortunately, I don't know of any two compilers that mangle
method names in the same way.  So don't think your <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> work with an
executable compiled with another compiler!
</p>

<h4>Attempt #2</h4>

<p>
For those of you experienced in object oriented programming, you know that
every class can be broken into two concepts:  an interface and a <b style="color: white; background-color: rgb(136, 0, 0);">factory</b>.
A <b style="color: white; background-color: rgb(136, 0, 0);">factory</b> is a mechanism for creating objects, and an interface allows you to
communicate with them.  The next version of Window.h will separate these
concepts.  Notice that you no longer need to export the class (you
have to export the <b style="color: white; background-color: rgb(136, 0, 0);">factory</b> function though!), as it is
abstract:  all method calls go through the object's vtable, not
through a direct linking to the <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b>.  Only the call to the <b style="color: white; background-color: rgb(136, 0, 0);">factory</b>
function calls directly into the <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b>.
</p>

<pre>// Window.h

#include &lt;string&gt;

class Window {
public:
  virtual ~Window() { }
  virtual void setTitle(std::string title) = 0;
  virtual std::string getTitle() = 0;
};

Window* DLLIMPORT CreateWindow(std::string title);
</pre>

<p>
This is much better.  The code that uses window objects doesn't care
what actual type the window object is, just that it implements the
Window interface.  However, there is still a problem: Different
compilers mangle symbol names differently, so the
<code>CreateWindow</code> function in DLLs generated by different
compilers will have a different names.  This means that if you compile
the windowing <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> with Visual C++ 6, you won't be able to use it in
Borland C++, and vice versa.  Fortunately, the C++ standard lets us
disable symbol mangling on specified names, via <code>extern
"C"</code>.
</p>

<p>
Some of you may have noticed another problem with this code.
Different compilers implement the standard C++ library differently.
In the less obvious case, some people replace their compiler's
implementation of the library with another (such as <a href="http://stlport.org/">STLPort</a>).  Since you can't depend on STL
objects being binary compatible across compilers, you cannot safely use them
in your <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> interfaces.
</p>

<p>
If a C++ ABI is ever created for <b style="color: black; background-color: rgb(255, 255, 102);">Windows</b>, it will need to specify
exactly how to interface with every class in the standard library, but
I don't see this happening anytime soon.
</p>

<p>
The final problem here is a minor one.  By convention, COM methods and
<b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> functions use the __stdcall calling convention.  We can fix this
with the CALL macro I defined above.  (You'll want to rename it in
your project.)
</p>

<h4>Revision 3</h4>

<pre>// Window.h

class Window {
public:
  virtual ~Window() { }
  virtual void CALL setTitle(const char* title) = 0;
  virtual const char* CALL getTitle() = 0;
};

extern "C" Window* CALL CreateWindow(const char* title);
</pre>

<p>
We're almost there!  This particular interface will probably work in a lot of
situations.  However, the virtual destructor makes things a little
interesting...  Since COM doesn't use virtual destructors, you can't depend
on different compilers to use them identically.  However, you can replace the
virtual destructor with a virtual method which, in the implementation class,
is implemented by <code>delete this;</code>  This way, both construction
and destruction are implemented on the same side of the <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> boundary.  For
example, if you try to use a VC++ 6 debug <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> alongside a release executable,
you'll either crash or run into warnings like "Value of ESP not saved
across function call".  This error occurs because the debug version of
the VC++ runtime library has a different allocator than the release
version.  Since the two allocators are not compatible, we cannot
allocate <b style="color: black; background-color: rgb(255, 102, 255);">memory</b> on one side of the <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> boundary and delete it on the
other.
</p>

<p>
"But how is a virtual destructor different from another virtual
method?"  Virtual destructors are not responsible for deallocating the
<b style="color: black; background-color: rgb(255, 102, 255);">memory</b> used by the object:  They are simply called to perform
necessary cleanup before the object is deallocated.  The executable
that uses your <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> will try to free the object's <b style="color: black; background-color: rgb(255, 102, 255);">memory</b> itself.  On
the other hand, the <code>destroy()</code> method <i>is</i>
responsible for deallocating <b style="color: black; background-color: rgb(255, 102, 255);">memory</b>, so all new and delete calls stay
on the same side of the <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> boundary.
</p>

<p>
It's also a good idea to make the interface's destructor protected so that
users of the interface can't inadvertently use delete on it.
</p>

<h4>Revision 4</h4>

<pre>// Window.h

class Window {
protected:
  ~Window() { }  // use destroy()

public:
  virtual void CALL destroy() = 0;
  virtual void CALL setTitle(const char* title) = 0;
  virtual const char* CALL getTitle() = 0;
};

extern "C" Window* CreateWindow(const char* title);
</pre>

<p>
Since this code doesn't use any semantics not defined by COM, it should work
flawlessly across compilers and configuration settings.  Unfortunately, it's
not ideal.  You have to remember to delete objects with
<code>object-&gt;destroy();</code>, which isn't nearly as intuitive as
<code>delete object;</code>.  Perhaps more importantly, you can no
longer use <code>std::auto_ptr</code> on objects of this type.
<code>auto_ptr</code> wants to delete the object it owns with
<code>delete object;</code>.  Is there a way to make the syntax
<code>delete object;</code> actually call <code>object-&gt;destroy();</code>?
Yes.  Here's where things get a little weird...  You can overload
<code>operator delete</code> for the interface and have it call destroy().
Since operator delete takes a void pointer, you'll have to assume you
never call Window::operator delete on anything that isn't a Window.  This
is a pretty safe assumption.  Here's the operator implementation:
</p>

<pre>...

  void operator delete(void* p) {
    if (p) {
      Window* w = static_cast&lt;Window*&gt;(p);
      w-&gt;destroy();
    }
   }

...
</pre>

<p>
Looks pretty good...  You can now use auto_ptr again, and you still
have a stable binary interface.  When you recompile and test your new
code (you <em>are</em> testing, right??), you'll notice that there is
a stack overflow in <code>WindowImpl::destroy</code>!  What's going
on?  If you remember how the destroy method is implemented, you'll see
that it simply executes <code>delete this;</code>.  Since the interface
overloads <code>operator delete</code>, <code>WindowImpl::destroy</code>
calls <code>Window::operator delete</code> which calls
<code>WindowImpl::destroy</code>...  ad infinitum.  The solution to
this particular problem is to overload operator delete in the
implementation class to call the global operator delete:

</p><pre>...

  void operator delete(void* p) {
    ::operator delete(p);
  }

...
</pre>

<h4>Finishing Touches</h4>

<p>
If your system has a lot of interfaces and implementations, you'll find that
you'll want some way to automate undefining operator delete.  Fortunately,
this is possible too.  Simply create a templated class called DefaultDelete
and instead of deriving your implementation class from interface I, derive
from class DefaultDelete&lt;I&gt;.  Here's DefaultDelete's definition:
</p>

<pre>template&lt;typename T&gt;
class DefaultDelete : public T {
public:
  void operator delete(void* p) {
    ::operator delete(p);
  }
};
</pre>

<h4>Final Implementation</h4>

<p>
Here is the final version of the code.
</p>

<pre>// Window.h

class Window {
public:
  virtual void CALL destroy() = 0;
  virtual void CALL setTitle(const char* title) = 0;
  virtual const char* CALL getTitle() = 0;

  void operator delete(void* p) {
    if (p) {
      Window* w = static_cast&lt;Window*&gt;(p);
      w-&gt;destroy();
    }
  }
};

extern "C" Window* CALL CreateWindow(const char* title);
</pre>

<pre>// Window.cpp
#include &lt;string&gt;
#include &lt;<b style="color: black; background-color: rgb(255, 255, 102);">windows</b>.h&gt;
#include "DefaultDelete.h"

class WindowImpl : public DefaultDelete&lt;Window&gt; {
public:
  WindowImpl(HWND window) {
    m_window = window;
  }

  ~WindowImpl() {
    DestroyWindow(m_window);
  }

  void CALL destroy() {
    delete this;
  }

  void CALL setTitle(const char* title) {
    SetWindowText(m_window, title);
  }

  const char* CALL getTitle() {
    char title[512];
    GetWindowText(m_window, title, 512);
    m_title = title;  // save the title past the call
    return m_title.c_str();
  }

private:
  HWND window;
  std::string m_title;
};

Window* CALL CreateWindow(const char* title) {
  // create the <b style="color: black; background-color: rgb(160, 255, 255);">Win32</b> window object
  HWND window = ::CreateWindow(..., title, ...);
  return (window ? new WindowImpl(window) : 0);
}
</pre>

<pre>// DefaultDelete.h

template&lt;typename T&gt;
class DefaultDelete : public T {
public:
  void operator delete(void* p) {
    ::operator delete(p);
  }
};
</pre>


<h4>Summary</h4>

<p>
That's about it.  In closure, I'll enumerate guidelines to keep in mind
when creating C++ interface.  You can look back on this as a reference or
use it to help solidify your knowledge.
</p>

<ul>
<li>All interface classes should be completely abstract.  Every method should
be pure virtual.  (Or inline...  you could safely write inline
convenience methods that call other methods.) </li>
<li>All global functions should be <code>extern "C"</code> to prevent
incompatible name mangling.  Also, exported functions and methods
should use the <code>__stdcall</code> calling convention, as <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b>
functions and COM
traditionally use that calling convention.  This way, if a user of the
library is compiling with <code>__cdecl</code> by default, the calls
into the <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> will still use the correct convention.</li>
<li>Don't use the standard C++ library.</li>
<li>Don't use exception handling.</li>
<li>Don't use virtual destructors.  Instead, create a destroy() method and an
overloaded <code>operator delete</code> that calls destroy().</li>
<li>Don't allocate <b style="color: black; background-color: rgb(255, 102, 255);">memory</b> on one side of the <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b> boundary and free it
on the other.  Different DLLs and executables can be built with
different heaps, and using different heaps to allocate and free
chunks of <b style="color: black; background-color: rgb(255, 102, 255);">memory</b> is a sure recipe for a crash.  For example, don't
inline your <b style="color: black; background-color: rgb(255, 102, 255);">memory</b> allocation functions so that they could be built
differently in the executable and <b style="color: black; background-color: rgb(255, 153, 153);">DLL</b>.</li>
<li>Don't use overloaded methods in your interface.  Different
compilers order them within the vtable differently.</li>
</ul>

<h4>References</h4>

<ul>
<li>
  <a href="http://stlport.org/">STLPort</a> is an alternate implementation
  of the STL.
</li>
<li>
  <a href="http://www.sgi.com/tech/stl/">SGI</a> has another standard C++
  library implementation.
</li>
<li>
  The <a href="http://corona.sf.net/">Corona</a> image I/O library uses the
  techniques introduced in this article.
</li>
</ul>

<h4>Feedback</h4>

<p>
I would really like feedback on this article.  Was any part unclear?  Do you
want more details about a particular situation?  Is any of the code wrong?
Send e-mail to
<a href="mailto:aegis@aegisknight.org">aegis@aegisknight.org</a>.
</p>

</body></html>
cppcompat.html (23,170 bytes)   

ringerc

2005-08-08 08:09

reporter   ~0005928

Uploaded some information that might be of interest - cppcompat.html .

Qt also apparently has some magic for this. It may well be that we can exploit that to make life easier.

Some other interesting articles (already mentioned elsewhere, but put here so they don't get lost):

http://www.lenholgate.com/archives/000419.html
http://discuss.joelonsoftware.com/default.asp?design.4.169899.4
http://mail.gnome.org/archives/xml/2001-October/msg00080.html

It sounds like this is mostly an issue for C++ code, but that C code linked to a different runtime library will also be affected. My understanding is that it's not that big a deal if we're doing our own self-contained bundle installers, but could be problematic for people wanting to build out-of-tree plugins, link to 3rd party libs (esp C++ libs), etc.

jghali

2005-08-08 08:11

administrator   ~0005929

A little correction about the b) point. Although it is possible to link modules using different C or C++ run-time, this kind of thing is hazardous. The real point is that user expected to be able to compile plugins using the runtime they want...

ringerc

2005-08-08 08:59

reporter   ~0005930

Last edited: 2005-08-08 09:01

I'm not sure I understand. Surely being able to compile plugins using the runtime they want implies that the plugins are linked against that runtime, which may be different to that of the main app or of some other libraries used?

I agree that it certainly does sound hazardous - I'd go so far as to say "insane without a strict ABI standard, and there isn't one." I'm confused by your comment though, as you seem to imply that's not what was meant in (b).

I guess (b) could be taken to mean statically linking modules compiled with different runtimes into a single executable image. It was meant to mean dynamically linking different DLLs built with different runtimes. [Update: Re-worded to clarify].

jghali

2005-08-08 09:05

administrator   ~0005931

>>It was meant to mean dynamically linking different DLLs built with different runtimes. [Update: Re-worded to clarify].

Now, we understand each other...

jghali

2011-06-10 23:05

administrator   ~0026352

Closing that one, have not encountered issues related to cross dll memory handling for a while

Issue History

Date Modified Username Field Change
2005-08-08 07:50 ringerc New Issue
2005-08-08 07:50 ringerc Status new => confirmed
2005-08-08 07:51 ringerc Note Added: 0005927
2005-08-08 07:52 ringerc Relationship added related to 0000015
2005-08-08 07:52 ringerc Relationship added related to 0002097
2005-08-08 07:57 ringerc Description Updated
2005-08-08 07:57 ringerc Additional Information Updated
2005-08-08 07:58 ringerc Relationship added related to 0001961
2005-08-08 07:59 ringerc File Added: cppcompat.html
2005-08-08 08:09 ringerc Note Added: 0005928
2005-08-08 08:11 jghali Note Added: 0005929
2005-08-08 08:59 ringerc Note Added: 0005930
2005-08-08 09:00 ringerc Description Updated
2005-08-08 09:01 ringerc Note Edited: 0005930
2005-08-08 09:05 jghali Note Added: 0005931
2005-08-10 09:14 ringerc Relationship added related to 0002398
2005-08-10 09:39 ringerc Relationship deleted related to 0001961
2005-12-03 19:54 cbradney Status confirmed => assigned
2005-12-03 19:54 cbradney Assigned To => jghali
2005-12-21 13:33 plinnell Relationship added related to 0002463
2006-01-27 01:02 plinnell Relationship deleted related to 0000015
2011-06-10 23:05 jghali Note Added: 0026352
2011-06-10 23:05 jghali Status assigned => resolved
2011-06-10 23:05 jghali Resolution open => fixed
2011-06-10 23:05 jghali Status resolved => closed