Hi! I'm preparing a patch (some of you are already aware of it) and in order to do it I need to create a new COM interface and its implementation. I've created it, but when compiling, it fails at linking time saying a lot of "undefined reference to vtable/VTT" errors. I thought I was doing something wrong in my C++ code, so I replicated INetworkAdapter and NetworkAdapter in a new class and it still gives me the same linker error. I'm clueless about what is the problem.. there must be something else that I have to do beside writing the code and adding the interface to the xidl file but I don't know what it is so please help me! Attached to this email you can find the patch and the errors.
Thanks in advance,
Eduardo Robles Elvira.
errors
Description: Binary data
Index: src/VBox/Main/include/NetworkAdapterImpl.h
===================================================================
--- src/VBox/Main/include/NetworkAdapterImpl.h (revisión: 18845)
+++ src/VBox/Main/include/NetworkAdapterImpl.h (copia de trabajo)
@@ -29,6 +29,61 @@
class Machine;
class GuestOSType;
+class ATL_NO_VTABLE NetworkAdapterRef :
+ public VirtualBoxBaseNEXT,
+ public VirtualBoxSupportErrorInfoImpl <NetworkAdapterRef, INetworkAdapterRef>,
+ public VirtualBoxSupportTranslation <NetworkAdapterRef>,
+ public INetworkAdapterRef
+{
+public:
+ VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (NetworkAdapterRef)
+
+ DECLARE_NOT_AGGREGATABLE(NetworkAdapterRef)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(NetworkAdapterRef)
+ COM_INTERFACE_ENTRY(ISupportErrorInfo)
+ COM_INTERFACE_ENTRY(INetworkAdapterRef)
+ END_COM_MAP()
+
+ NS_DECL_ISUPPORTS
+
+ DECLARE_EMPTY_CTOR_DTOR (NetworkAdapterRef)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init ( const Guid &machineId, ULONG mSlot );
+ void uninit();
+
+ // INetworkAdapterRef properties
+ STDMETHOD(COMGETTER(Slot)) (ULONG *aSlot);
+ STDMETHOD(COMGETTER(MachineId)) (OUT_GUID aId);
+
+ // public methods only for internal purposes
+ const Guid &machineId() const { return mData.machineId; }
+ const ULONG &slot() const { return mData.slot; }
+
+ // for VirtualBoxSupportErrorInfoImpl
+ static const wchar_t *getComponentName() { return L"NetworkAdapterRef"; }
+
+private:
+
+ struct Data
+ {
+ Data() : machineId (0), slot (0) {}
+
+ /** The UUID of the parent machine. */
+ const Guid machineId;
+ /** The slot in which this netowrk adapter resides in the parent machine. */
+ const ULONG slot;
+ };
+
+ Data mData;
+};
+
class ATL_NO_VTABLE NetworkAdapter :
public VirtualBoxBaseNEXT,
public VirtualBoxSupportErrorInfoImpl <NetworkAdapter, INetworkAdapter>,
@@ -36,14 +91,14 @@
public INetworkAdapter
{
public:
-
+ typedef std::list <ComObjPtr <NetworkAdapterRef> > NetworkAdapterRefList;
struct Data
{
Data()
: mSlot (0), mEnabled (FALSE)
, mAttachmentType (NetworkAttachmentType_Null)
, mCableConnected (TRUE), mLineSpeed (0), mTraceEnabled (FALSE)
- , mHostInterface ("") /* cannot be null */
+ , mHostInterface ("") /* cannot be null */, mMesh (FALSE)
{}
bool operator== (const Data &that) const
@@ -58,7 +113,8 @@
mTraceEnabled == that.mTraceEnabled &&
mHostInterface == that.mHostInterface &&
mInternalNetwork == that.mInternalNetwork &&
- mNATNetwork == that.mNATNetwork);
+ mNATNetwork == that.mNATNetwork &&
+ mMesh == that.mMesh);
}
NetworkAdapterType_T mAdapterType;
@@ -73,6 +129,8 @@
Bstr mHostInterface;
Bstr mInternalNetwork;
Bstr mNATNetwork;
+ BOOL mMesh;
+ NetworkAdapterRefList mMeshNeighbours;
};
VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (NetworkAdapter)
@@ -122,6 +180,10 @@
STDMETHOD(COMSETTER(LineSpeed)) (ULONG aSpeed);
STDMETHOD(COMGETTER(TraceFile)) (BSTR *aTraceFile);
STDMETHOD(COMSETTER(TraceFile)) (IN_BSTR aTraceFile);
+ STDMETHOD(COMGETTER(MeshEnabled)) (BOOL *aEnabled);
+ STDMETHOD(COMSETTER(MeshEnabled)) (BOOL aEnabled);
+ STDMETHOD(COMGETTER(MeshNeighbours)) (ComSafeArrayOut (INetworkAdapterRef *, aNetworkAdapterRefs));
+ STDMETHOD(COMGETTER(Parent)) (IMachine **aMachine);
// INetworkAdapter methods
STDMETHOD(AttachToNAT)();
@@ -146,6 +208,7 @@
// (ensure there is a caller and a read lock before calling them!)
const Backupable <Data> &data() const { return mData; }
+ const ComObjPtr <Machine, ComWeakRef> &parent() const { return mParent; }
// for VirtualBoxSupportErrorInfoImpl
static const wchar_t *getComponentName() { return L"NetworkAdapter"; }
Index: src/VBox/Main/NetworkAdapterImpl.cpp
===================================================================
--- src/VBox/Main/NetworkAdapterImpl.cpp (revisión: 18845)
+++ src/VBox/Main/NetworkAdapterImpl.cpp (copia de trabajo)
@@ -682,6 +682,80 @@
return S_OK;
}
+
+STDMETHODIMP NetworkAdapter::COMGETTER(MeshEnabled) (BOOL *aEnabled)
+{
+ CheckComArgOutPointerValid(aEnabled);
+
+ AutoCaller autoCaller (this);
+ CheckComRCReturnRC (autoCaller.rc());
+
+ AutoReadLock alock (this);
+
+ *aEnabled = mData->mMesh;
+
+ return S_OK;
+}
+
+STDMETHODIMP NetworkAdapter::COMSETTER(MeshEnabled) (BOOL aEnabled)
+{
+ AutoCaller autoCaller (this);
+ CheckComRCReturnRC (autoCaller.rc());
+
+ /* the machine needs to be mutable */
+ Machine::AutoMutableStateDependency adep (mParent);
+ CheckComRCReturnRC (adep.rc());
+
+ AutoWriteLock alock (this);
+
+ if (mData->mMesh != aEnabled)
+ {
+ mData.backup();
+ mData->mMesh = aEnabled;
+
+ /* leave the lock before informing callbacks */
+ alock.unlock();
+
+ mParent->onNetworkAdapterChange (this);
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP NetworkAdapter::
+COMGETTER(MeshNeighbours) (ComSafeArrayOut (INetworkAdapterRef *, aNetworkAdapterRefs))
+{
+ if (ComSafeArrayOutIsNull (aNetworkAdapterRefs))
+ return E_POINTER;
+
+ AssertReturn (mData->mMesh, E_FAIL);
+
+ AutoCaller autoCaller (this);
+ CheckComRCReturnRC (autoCaller.rc());
+
+ AutoReadLock alock (this);
+
+ SafeIfaceArray <INetworkAdapterRef> networkAdapterRefs (mData->mMeshNeighbours);
+ networkAdapterRefs.detachTo (ComSafeArrayOutArg (aNetworkAdapterRefs));
+
+ return S_OK;
+}
+
+STDMETHODIMP NetworkAdapter::COMGETTER(Parent) (IMachine **aParent)
+{
+ CheckComArgOutPointerValid(aParent);
+
+ AutoCaller autoCaller (this);
+ CheckComRCReturnRC (autoCaller.rc());
+
+ AutoReadLock alock (this);
+
+ /* mParent is const, no need to lock */
+ mParent.queryInterfaceTo (aParent);
+
+ return S_OK;
+}
+
// INetworkAdapter methods
////////////////////////////////////////////////////////////////////////////////
@@ -950,6 +1024,22 @@
Bstr name = attachmentNode.stringValue ("name");
/* name can be empty, but not null */
ComAssertRet (!name.isNull(), E_FAIL);
+ mData->mMesh = attachmentNode.value <bool> ("mesh");
+
+ if(mData->mMesh)
+ {
+ Key meshNeighbourNode;
+ while (!(meshNeighbourNode = attachmentNode.findKey ("MeshNeighbour")).isNull())
+ {
+ Guid machineId = meshNeighbourNode.value<Guid>("machine");
+ ULONG aSlot = meshNeighbourNode.value <ULONG> ("slot");
+
+ NetworkAdapterRef *networkAdapterRef = new NetworkAdapterRef();
+ networkAdapterRef->init(machineId, aSlot);
+ ComObjPtr <NetworkAdapterRef> aRef(networkAdapterRef);
+ mData->mMeshNeighbours.push_back(aRef);
+ }
+ }
rc = COMSETTER(HostInterface) (name);
CheckComRCReturnRC (rc);
@@ -1060,6 +1150,17 @@
#if defined(VBOX_WITH_NETFLT)
Assert (!mData->mHostInterface.isNull());
attachmentNode.setValue <Bstr> ("name", mData->mHostInterface);
+ attachmentNode.setValue <bool> ("mesh", mData->mMesh);
+
+ if(mData->mMesh)
+ {
+ for (NetworkAdapterRefList::const_iterator it = mData->mMeshNeighbours.begin(); it != mData->mMeshNeighbours.end(); ++ it)
+ {
+ Key meshNeighbourNode = attachmentNode.createKey ("MeshNeighbour");
+ meshNeighbourNode.setValue <Guid> ("machine", (*it)->machineId());
+ meshNeighbourNode.setValue <ULONG> ("slot", (*it)->slot());
+ }
+ }
#endif
break;
}
@@ -1253,4 +1354,102 @@
LogFlowThisFunc (("generated MAC: '%s'\n", strMAC));
mData->mMACAddress = strMAC;
}
+
+
+
+
+// constructor / destructor
+////////////////////////////////////////////////////////////////////////////////
+
+DEFINE_EMPTY_CTOR_DTOR (NetworkAdapterRef)
+
+HRESULT NetworkAdapterRef::FinalConstruct()
+{
+ return S_OK;
+}
+
+void NetworkAdapterRef::FinalRelease()
+{
+ uninit ();
+}
+
+// public initializer/uninitializer for internal purposes only
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Initializes the network adapter object.
+ */
+HRESULT NetworkAdapterRef::init (const Guid &machineId, ULONG aSlot)
+{
+ LogFlowThisFunc (("machineId=%p, aSlot=%d\n", machineId, aSlot));
+
+ ComAssertRet (aSlot < SchemaDefs::NetworkAdapterCount, E_INVALIDARG);
+
+ /* Enclose the state transition NotReady->InInit->Ready */
+ AutoInitSpan autoInitSpan (this);
+ AssertReturn (autoInitSpan.isOk(), E_FAIL);
+
+ /* initialize data */
+ unconst(mData.slot) = aSlot;
+ unconst(mData.machineId) = machineId;
+
+ /* Confirm a successful initialization */
+ autoInitSpan.setSucceeded();
+
+ return S_OK;
+}
+
+/**
+ * Uninitializes the instance and sets the ready flag to FALSE.
+ * Called either from FinalRelease() or by the parent when it gets destroyed.
+ */
+void NetworkAdapterRef::uninit()
+{
+ LogFlowThisFunc (("\n"));
+
+ /* Enclose the state transition Ready->InUninit->NotReady */
+ AutoUninitSpan autoUninitSpan (this);
+ if (autoUninitSpan.uninitDone())
+ return;
+
+ unconst (mData.machineId).clear();
+
+ unconst (mData.slot) = 0;
+}
+// INetworkAdapterRef properties
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Returns the GUID.
+ *
+ * @returns COM status code
+ * @param aId Address of result variable.
+ */
+STDMETHODIMP NetworkAdapterRef::COMGETTER(MachineId)(OUT_GUID aId)
+{
+ CheckComArgOutPointerValid(aId);
+
+ AutoCaller autoCaller (this);
+ CheckComRCReturnRC (autoCaller.rc());
+
+ /* this is const, no need to lock */
+ mData.machineId.cloneTo (aId);
+
+ return S_OK;
+}
+
+STDMETHODIMP NetworkAdapterRef::COMGETTER(Slot) (ULONG *aSlot)
+{
+ CheckComArgOutPointerValid(aSlot);
+
+ AutoCaller autoCaller (this);
+ CheckComRCReturnRC (autoCaller.rc());
+
+ AutoReadLock alock (this);
+
+ *aSlot = mData.slot;
+
+ return S_OK;
+}
+
/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Index: src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- src/VBox/Main/idl/VirtualBox.xidl (revisión: 18845)
+++ src/VBox/Main/idl/VirtualBox.xidl (copia de trabajo)
@@ -10929,6 +10929,26 @@
<desc>Intel PRO/1000 MT Server network card (82545EM).</desc>
</const>
</enum>
+
+ <interface
+ name="INetworkAdapterRef" extends="$unknown"
+ uuid="2a90d238-5eb4-109b-ce14-1488a720c2dd"
+ wsmap="managed"
+ >
+ <desc>
+ Represents a reference to a virtual network adapter using two attributes:
+ the machine to which the network adpater is attached, and the slot in
+ which the network adapter is attached in that machine. It's used instead
+ of INetworkAdapter to reference NetworkAdapters that might not have been
+ created yet.
+ </desc>
+ <attribute name="machineId" type="uuid" readonly="yes">
+ <desc>The machine ID to which this network interface is attached to.</desc>
+ </attribute>
+ <attribute name="slot" type="unsigned long" readonly="yes">
+ <desc>The slot in which the network adapter is attached to.</desc>
+ </attribute>
+ </interface>
<interface
name="INetworkAdapter" extends="$unknown"
@@ -11026,6 +11046,29 @@
</desc>
</attribute>
+
+ <attribute name="meshEnabled" type="boolean">
+ <desc>
+ Flag whether this network will be mesh, meaning that instead of everyone
+ being neighbours, a given network interface is connected to a subset of
+ other network interfaces, forming a mesh network.
+ </desc>
+ </attribute>
+
+ <attribute name="parent" type="IMachine" readonly="yes">
+ <desc>
+ Associated parent object.
+ </desc>
+ </attribute>
+
+ <attribute name="meshNeighbours" type="INetworkAdapterRef" safearray="yes" readonly="yes">
+ <desc>
+ List of all the other network adapters connected to this one in a mesh
+ network. In order to call get the list, the network adapter must be
+ in mesh mode or else it will return E_FAIL.
+ </desc>
+ </attribute>
+
<method name="attachToNAT">
<desc>
Attach the network adapter to the Network Address Translation (NAT) interface._______________________________________________ vbox-dev mailing list [email protected] http://vbox.innotek.de/mailman/listinfo/vbox-dev
