I got stuck at the EncodableTypes. I Included the snippets of code that matter, so you don't have to jump into the header files, if this is a problem due to closed source please feel free to notify me and to remove it then I will refrain from doing so in the future.
A word about research effort beforehand:
I have read numerous questions regarding linker errors on stackoverflow and have checked all the project's properties a gazillion times, read about calling conventions in this (very interesting and truly recommendable) article http://www.unixwiz.net/techtips/win32-callconv.html and double checked my imports. None of it helped the slightest bit.
After a few hours of research I am turning to you for help (obviously).
A little bit of background:
Another person implemented the server I have to integrate my code into. The server works - another team used it in another smaller project. I started implementing a provider, using the UAModeler produced 168 single files I had to go through to find errors.
Now since my provider compiles and everything else also does, I added it to the server (pfInit...) linking all the other (8) projects together. Trying to compile that bit resulted in quite a few unresolved external symbols which I was able to fix, except for these three errors:
I am working in VS2008 on a Windows7 64Bit machine - in case that matters.
Code: Select all
1>------ Build started: Project: demoserver, Configuration: Debug Win32 ------
1>Linking...
1>myProvider.lib(uaprovider_myProvider_subscription.obj) : error LNK2001:
unresolved external symbol _OpcUa_Range_EncodeableType
1>myProvider.lib(uaprovider_myProvider_nodes_2.obj) : error LNK2001:
unresolved external symbol _OpcUa_EnumValueType_EncodeableType
1>myProvider.lib(uaprovider_myProvider_nodes_2.obj) : error LNK2001:
unresolved external symbol _OpcUa_Argument_EncodeableType
1>..\..\..\..\bin\demoserverd.exe : fatal error LNK1120: 3 unresolved externals
1>demoserver - 4 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 8 up-to-date, 0 skipped ==========
The "externals" are declared in "opctypes.h" and defined in the "opctypes.c"
Both files are in the same solution in a project called uastack which compiles to a DLL. The dependency check boxes in the demoserver-project which fails to compile are all checked and I compiled all the other projects by them selves (clean + rebuild) so now I really don't know what else to do.
The "unresolved external" is declared in the header
Code: Select all
OPCUA_IMEXPORT extern struct _OpcUa_EncodeableType OpcUa_EnumValueType_EncodeableType;
Code: Select all
/*============================================================================
* OpcUa_EnumValueType_EncodeableType
*===========================================================================*/
struct _OpcUa_EncodeableType OpcUa_EnumValueType_EncodeableType =
{
"EnumValueType",
OpcUaId_EnumValueType,
OpcUaId_EnumValueType_Encoding_DefaultBinary,
OpcUaId_EnumValueType_Encoding_DefaultXml,
OpcUa_Null,
sizeof(OpcUa_EnumValueType),
(OpcUa_EncodeableObject_PfnInitialize*)OpcUa_EnumValueType_Initialize,
(OpcUa_EncodeableObject_PfnClear*)OpcUa_EnumValueType_Clear,
(OpcUa_EncodeableObject_PfnGetSize*)OpcUa_EnumValueType_GetSize,
(OpcUa_EncodeableObject_PfnEncode*)OpcUa_EnumValueType_Encode,
(OpcUa_EncodeableObject_PfnDecode*)OpcUa_EnumValueType_Decode
#if OPCUA_ENCODEABLE_OBJECT_COMPARE_SUPPORTED
,(OpcUa_EncodeableObject_PfnCompare*)OpcUa_EnumValueType_Compare
#endif /* OPCUA_ENCODEABLE_OBJECT_COMPARE_SUPPORTED */
#if OPCUA_ENCODEABLE_OBJECT_COPY_SUPPORTED
,(OpcUa_EncodeableObject_PfnCopy*)OpcUa_EnumValueType_Copy,
(OpcUa_EncodeableObject_PfnCopyTo*)OpcUa_EnumValueType_CopyTo
#endif /* OPCUA_ENCODEABLE_OBJECT_COPY_SUPPORTED */
};
#endif
Some lines before is a preprocessor directive saying
Code: Select all
#ifndef OPCUA_EXCLUDE_EnumValueType
So I put that one and the corresponding
Code: Select all
#endif
At the very bottom there is another table of known types, which features a whole list of statements like this one:
Code: Select all
/*============================================================================
* Table of known types.
*===========================================================================*/
static OpcUa_EncodeableType* g_OpcUa_KnownEncodeableTypes[] =
{
#ifndef OPCUA_EXCLUDE_EnumValueType
&OpcUa_EnumValueType_EncodeableType,
#endif
Code: Select all
/**
@brief Creates an Encodeable Object at the given ExtensionObject.
@param pType [in] The type of the object.
@param pExtension [in/out] The extension object to which the encodeable object gets attached.
@param ppEncodeableObject [in/out] Pointer to the encodeable object.
*/
OPCUA_EXPORT
OpcUa_StatusCode OpcUa_EncodeableObject_CreateExtension(
OpcUa_EncodeableType* pType,
OpcUa_ExtensionObject* pExtension,
OpcUa_Void** ppEncodeableObject);
( I tried to do my best to distil the code, hope it is still readable to you but the file has 700ish lines.)
Code: Select all
/**
* Adds the ApplicationMemoryAreaEnum nodes to the address space
*/
OpcUa_StatusCode UaProvider_myProvider_AddApplicationMemoryAreaEnum()
{
UaServer_AddressSpace* pAddressSpace = &(g_pMyProvider->AddressSpace);
UaServer_AddressSpace* pServerAddressSpace = OpcUa_Null;
OpcUa_BaseNode *pDataTypeNode;
OpcUa_BaseNode *pParent;
OpcUa_BaseNode *pEnumValues;
OpcUa_EnumValueType *pEnumValue;
OpcUa_BaseNode *pModellingRule;
OpcUa_UInt32 *pArrayDimensions;
OpcUa_NodeId referenceTypeId;
OpcUa_NodeId parentNodeId;
OpcUa_NodeId modellingRuleId;
OpcUa_Variant value;
OpcUa_Int32 i = 0;
UaProvider_myProvider_NodeInfo nodeInfo;
OpcUa_InitializeStatus(OpcUa_Module_Server, "UaProvider_myProvider_AddApplicationMemoryAreaEnum");
OpcUa_ReferenceParameter(i);
g_pmyProviderCBInterface->AddressSpace_Get(0, &pServerAddressSpace);
OpcUa_Variant_Initialize(&value);
UaProvider_myProvider_NodeInfo_Initialize(&nodeInfo);
uStatus = UaProvider_myProvider_CreateNode(
pAddressSpace,
&pEnumValues,
pDataTypeNode,
&referenceTypeId,
&nodeInfo);
OpcUa_GotoErrorIfBad(uStatus);
value.Datatype = OpcUaType_ExtensionObject;
value.ArrayType = OpcUa_VariantArrayType_Array;
value.Value.Array.Length = 3;
value.Value.Array.Value.ExtensionObjectArray = (OpcUa_ExtensionObject*)UaServer_Alloc(sizeof(OpcUa_ExtensionObject) * 3);
for(i=0; i<3; i++)
{
OpcUa_ExtensionObject_Initialize(&value.Value.Array.Value.ExtensionObjectArray[i]);
}
i = 0;
OpcUa_EncodeableObject_CreateExtension(&OpcUa_EnumValueType_EncodeableType,
&value.Value.Array.Value.ExtensionObjectArray[ i++ ],
&pEnumValue);
pEnumValue->Value = 0;
OpcUa_EncodeableObject_CreateExtension(&OpcUa_EnumValueType_EncodeableType,
&value.Value.Array.Value.ExtensionObjectArray[ i++ ],
&pEnumValue);
pEnumValue->Value = 1;
OpcUa_EncodeableObject_CreateExtension(&OpcUa_EnumValueType_EncodeableType,
&value.Value.Array.Value.ExtensionObjectArray[ i++ ],
&pEnumValue);
pEnumValue->Value = 1;
}
Which makes me wonder: is this maybe a singleton and must I be able to find it somewhere in the depths of the libraries linked or do I still need to create an instance in the `OpcUa_StatusCode UaProvider_myProvider_AddApplicationMemoryAreaEnum()` function and assign any value to it, so it can be used? And if I added a declaration+definition, wouldn't that eventually corrupt the stuff this code is supposed to do (like use the same encoding for all types)?
I would really appreciate your help and advice.