For direct access use https://forums.oldunreal.com
It's been quite a while since oldunreal had an overhaul, but we are moving to another server which require some updates and changes. The biggest change is the migration of our old reliable YaBB forum to phpBB. This system expects you to login with your username and old password known from YaBB.
If you experience any problems there is also the usual "password forgotten" function. Don't forget to clear your browser cache!
If you have any further concerns feel free to contact me: Smirftsch@oldunreal.com

Is there a proper fix for TArray linkage?

User avatar
[]KAOS[]Casey
OldUnreal Member
Posts: 4497
Joined: Sun Aug 07, 2011 4:22 am
Location: over there

Is there a proper fix for TArray linkage?

Post by []KAOS[]Casey »

I want/need to use "appLoadFileToArray" for loading a .dds into memory so I can check if it's a proper magic number, and load it into a buffer and so on..

Is there some proper way to trick the compiler to link properly for UT binaries?

If not, a workaround would suffice for this instance.
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Is there a proper fix for TArray linkage?

Post by han »

Whats the problem with it? Are you sure it's not caused by the msvc version you are using? At least for building ALAudio I ended in removing the ENGINE_API specifier on FSoundData to get around some linker issues.
HX on Mod DB. Revision on Steam. Löffels on Patreon.
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Is there a proper fix for TArray linkage?

Post by han »

Despite.. why don't you use a UFactory?
HX on Mod DB. Revision on Steam. Löffels on Patreon.
User avatar
[]KAOS[]Casey
OldUnreal Member
Posts: 4497
Joined: Sun Aug 07, 2011 4:22 am
Location: over there

Re: Is there a proper fix for TArray linkage?

Post by []KAOS[]Casey »

Because I'm implementing DDS importing by effectively creating my own UFactory, UT99 doesn't have DDS importer to my knowledge.

I'm also absolutely sure it is caused by MSVC, which is why I'm asking here.

It's the same old song and dance -- constructors and destructors, as well as other miscellaneous functions aren't linking.

I'll probably just end up coding my own way to load the file into memory instead of using unreals implementation.
Last edited by []KAOS[]Casey on Tue Sep 06, 2016 9:07 pm, edited 1 time in total.
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Is there a proper fix for TArray linkage?

Post by han »

Can you post the link erorrs? I'm not at home and right now have no access to msvc 2013... I suggested the UFactory as you already get the file data passed in and you wont need to use the appLoadfimetoarray this way. Otherwise you could use the filemanager to geg the filesize, appalloc and Ar.Serialize( ptf, size ). Or directly create the appropreciate structures for serializing the header.
HX on Mod DB. Revision on Steam. Löffels on Patreon.
User avatar
[]KAOS[]Casey
OldUnreal Member
Posts: 4497
Joined: Sun Aug 07, 2011 4:22 am
Location: over there

Re: Is there a proper fix for TArray linkage?

Post by []KAOS[]Casey »

Oh interesting,

I'll try that with the UFactory.

I will post the linker errors as soon as I'm home.
User avatar
[]KAOS[]Casey
OldUnreal Member
Posts: 4497
Joined: Sun Aug 07, 2011 4:22 am
Location: over there

Re: Is there a proper fix for TArray linkage?

Post by []KAOS[]Casey »

Code: Select all

1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: void __thiscall TArray::Remove(int,int)" (__imp_?Remove@?$TArray@E@@QAEXHH@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: void __thiscall TArray::Remove(int,int)" (__imp_?Remove@?$TArray@G@@QAEXHH@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: int __thiscall TArray::AddItem(unsigned char const &)" (__imp_?AddItem@?$TArray@E@@QAEHABE@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: int __thiscall TArray::Add(int)" (__imp_?Add@?$TArray@E@@QAEHH@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: unsigned char & __thiscall TArray::operator()(int)" (__imp_??R?$TArray@E@@QAEAAEH@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TArray::~TArray(void)" (__imp_??1?$TArray@E@@QAE@XZ)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TArray::TArray(void)" (__imp_??0?$TArray@E@@QAE@XZ)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: unsigned short & __thiscall TArray::operator()(int)" (__imp_??R?$TArray@G@@QAEAAGH@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TArray::~TArray(void)" (__imp_??1?$TArray@G@@QAE@XZ)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TArray::TArray(void)" (__imp_??0?$TArray@G@@QAE@XZ)
User avatar
[]KAOS[]Casey
OldUnreal Member
Posts: 4497
Joined: Sun Aug 07, 2011 4:22 am
Location: over there

Re: Is there a proper fix for TArray linkage?

Post by []KAOS[]Casey »

Looks like I might just have to install VC6 on a VM for this. Mips uses a few tarrays.
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: Is there a proper fix for TArray linkage?

Post by Masterkent »

Code: Select all

1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: void __thiscall TArray::Remove(int,int)" (__imp_?Remove@?$TArray@E@@QAEXHH@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: void __thiscall TArray::Remove(int,int)" (__imp_?Remove@?$TArray@G@@QAEXHH@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: int __thiscall TArray::AddItem(unsigned char const &)" (__imp_?AddItem@?$TArray@E@@QAEHABE@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: int __thiscall TArray::Add(int)" (__imp_?Add@?$TArray@E@@QAEHH@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: unsigned char & __thiscall TArray::operator()(int)" (__imp_??R?$TArray@E@@QAEAAEH@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TArray::~TArray(void)" (__imp_??1?$TArray@E@@QAE@XZ)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TArray::TArray(void)" (__imp_??0?$TArray@E@@QAE@XZ)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: unsigned short & __thiscall TArray::operator()(int)" (__imp_??R?$TArray@G@@QAEAAGH@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TArray::~TArray(void)" (__imp_??1?$TArray@G@@QAE@XZ)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TArray::TArray(void)" (__imp_??0?$TArray@G@@QAE@XZ)
The first question is: why are definitions of all these template specializations have to be obtained from dll? Why do you suppress implicit instantiation of these specializations?

The second question is: what code do you use to instantiate and export these specializations (for the given lists of template arguments) in that dll?
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Is there a proper fix for TArray linkage?

Post by han »

Looks like I might just have to install VC6 on a VM for this. Mips uses a few tarrays.
Fyi, msvc6 after install runs without issues even on Win10.

I could sent you my headers I use for ut, which has has quite some changes done in UnTemplate.h. might work for you.

Though I saw some post/thread by Hidor about another way fixing it some time ago, but afaik it wasnt on oldunreal, but this ut site.. I sent Smirftsch the link :p

You could also try removing the ENGINE_API on FMipMapBase or FMipMip... as this worked for FSojndData.
HX on Mod DB. Revision on Steam. Löffels on Patreon.
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: Is there a proper fix for TArray linkage?

Post by Masterkent »

ENGINE_API is just a macro which is expanded to __declspec(dllimport). When applied to a class, it is automatically applied to all its member functions. When applied to a member function of a class template, implicit instantiation of definition of the given member function will be suppressed, because the definition of a member function of a class template specialization is then supposed to be obtained from an external library. If external library does not provide the definition having exactly the same signature (which is distinguished by mangled function name), linking to the function fails.

When a member function of a class template is declared with dllexport (which can be achieved by declaring the whole class with dllexport), presence of the generic definition of the function is not sufficient for exporting any of its specializations. If you want to export a specialization (an instance) of a member function of a class template with a particular template-argument-list, you have to instantiate it. I don't remember if implicit instantiation is enough, but explicit instantiation should work. For a particular function it would be something like this:

Code: Select all

template void TArray::Remove(int, int);
// instantiates the definition of the member function of TArray from the generic definition
It is also possible to explicitly instantiate the whole class:

Code: Select all

template class TArray;
// instantiates the whole class TArray from the class template definition
Not sure if __declspec(dllexport) has to be present in either case.

Now about removing ENGINE_API. By removing __declspec(dllimport) for a particular function you allow implicit instantiation of the function definition from the generic definition available in the corresponding header file (so the current module will use its own definition of the function rather than expect that an external library will provide it). Then you must ensure that if several modules operate on the same object, the operations are consistent across modules. In particular, all modules shall use the same heap for memory allocations and deallocations.
Last edited by Masterkent on Wed Sep 07, 2016 1:07 pm, edited 1 time in total.
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Is there a proper fix for TArray linkage?

Post by han »

In any case the templates in UnTemplate.h use GMalloc for allocation/deallocation so this is not an issue at all. Also there are a lot of non UObject based classes inside the headers where all code you use or usually use is present, so removing the CORE_API macro on FString allows you too fix the plenty of bugs related to empty strings, have a more common plattform across different ue1 games.

In any case I prefer using MSVC6 for UE1 stuff...
HX on Mod DB. Revision on Steam. Löffels on Patreon.
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: Is there a proper fix for TArray linkage?

Post by Masterkent »

In any case I prefer using MSVC6 for UE1 stuff...
I never worked on native mods for Unreal/UT, so I can't tell how much the existing code base of U/UT relies on the specific behavior of MSVC 6. Nevertheless, I worked with MSVC 6 per se, and, from what I remember, it's an old piece of sh... with a lot of bugs and poor support of C++ features (even for '98 year) - especially with regard to templates. Nowadays I can't consider it other than as a museum specimen. Modern compilers offer much better language support and quality of generated code.
Last edited by Masterkent on Wed Sep 07, 2016 2:57 pm, edited 1 time in total.
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Is there a proper fix for TArray linkage?

Post by han »

As UE1 sort of contains it own standard library the sort of problematic template implementation is no issue. As for compiler bugs, I never ran into a single one so far, for uc i did.

The IDE itsself is imho the best vc ide ms ever created. And it's incredible fast whereas msvc 2013 is slow as hell.

As for generated code, you don't gain anything from compiling old code with it. A lot of the code uses a lot of branching as old optimizagion, while for really gaining perf one need to migrage the code to less branching and especially staying more local in mem and also especially remove a lot of asm opts and CORE_API stuff in UnMath.h. But still for make efficient use of SSE you do want a broader alignment than what your data usually gets passed in for you. What really gets a lot faster is using msvc2013 acos function, but this in turn will use a different runtime and you might get troubles with the internal states of the runtimes, etc. Afaik there was a nice article about the runtime problematic linked on the libpng page.

So in general you just gain problems when using a newer msvc version for ue1 games build with vc6 and virtually gain nothing.
HX on Mod DB. Revision on Steam. Löffels on Patreon.
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: Is there a proper fix for TArray linkage?

Post by Masterkent »

As UE1 sort of contains it own standard library the sort of problematic template implementation is no issue.
That library covers very few needs, and, for example, where possible, I'd rather use C++11/14 std::vector instead of nonsense like TArray.
As for compiler bugs, I never ran into a single one so far
You probably used a very small subset of language features. I faced with compiler bugs regularly. Sometimes compiler just crashed when trying to compile a valid code. In some cases I got hard-to-find bugs in compiled programs due to erroneously performed overload resolution or missing initialization of objects that had to be done according to the language rules.
As for generated  code, you don't gain anything from compiling old code with it.
I don't think so. Optimizers were improved a lot since those ancient times. E.g. new compilers can inline more functions. IIRC, link time code generation was not supported by VC++ 6 at all. Better inlining alone already can give a noticeable performance boost.
So in general you just gain problems when using a newer msvc version for ue1 games build with vc6 and virtually gain nothing.
I wonder what problems could arise there. Does that old code base rely on specific compiler bugs and/or undocumented behavior so much or what?
Last edited by Masterkent on Wed Sep 07, 2016 9:11 pm, edited 1 time in total.
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Is there a proper fix for TArray linkage?

Post by han »

UE1 doesn't use the STL stuff or any newer C++ additions, and you loose all integration into the UE1 framework when using std::vector. So what are in your opinion the shortcommings of TArray? Also because it wont use templates as much you dont run into the issues msvc6 has with templates, etc.

As for the optimizations, I do a lot of benchmarking on the rendering stuff, and the first non neglectable performance improvement turned out to be for acos, but in this case the advantage is just temporary as weighting face normals is regardlesd of the compiler too expansive at runtime on the cpu, and once this ends up in a compute shader, the perfhingsorman e advantage again vanishes.

Don't get me wrong, for anything new I would not use MSVC6, but imho for my work on UE1 games it is imho the best solution.
HX on Mod DB. Revision on Steam. Löffels on Patreon.
User avatar
[]KAOS[]Casey
OldUnreal Member
Posts: 4497
Joined: Sun Aug 07, 2011 4:22 am
Location: over there

Re: Is there a proper fix for TArray linkage?

Post by []KAOS[]Casey »

After inserted an edited UnTemplate.h provided by han, i got fewer linker errors

The code in question

Buffer is just a buffer of the whole .DDS texture as a const BYTE*

Code: Select all

Result *UTexture =  CastChecked(StaticConstructObject(UTexture::StaticClass(), 0, TEXT("TEMP"), 0 ) );
...
some DDS checking here
...
Result->Init(Width, Height);
Result->PostLoad();

...
more DDS checking, look for DXT1, etc.
...
new(Result->Mips)FMipmap( UBits, VBits,offset);
Result->Mips(i).Clear();
Result->Mips(i).DataArray.SetSize(offset);
appMemcpy( &Result->Mips(i).DataArray(0), Buffer, offset );

I can probably pastebin the whole code since this was written by smirf.

This also causes some linker errors:

Code: Select all

      UTexture* Result = ImportObject(T->GetOuter(),TEXT("TEMP"),0,*FoundFilename,this,0,0,GWarn); 
      if (Result)
      {
            Fmt = (ETextureFormat)Result->Format;
            T->Init(Result->USize,Result->VSize);
            if(Fmt != T->Format)
            {
                  T->Mips = Result->Mips;
                  T->Format = Fmt;
            }
            else T->Mips = Result->Mips;
            T->Palette = Result->Palette;
            Result->Destroy();
      }
which is weird, because it didn't before the untemplate change...
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: Is there a proper fix for TArray linkage?

Post by Masterkent »

UE1 doesn't use the STL stuff or any newer C++ additions, and you loose all integration into the UE1 framework when using std::vector.
A part of program, that does not directly invoke UE functions, may store its data in any suitable containers and use libraries that have no any relationship to UE.
So what are in your opinion the shortcommings of TArray?
It imposes specific requirements on data types which can be used as element types: zero-initialization of object's memory must be sufficient for its default construction, bitwise copy of object's memory must be sufficient for moving the object to a new memory location. Attempts to insert or relocate objects that do not satisfy these requirements may lead to appearance of objects with invalid internal state. std::vector is free of such issues, because it uses value-initialization (that invokes default constructor for objects having a non-trivial default ctor) instead of dumb filling memory with zero bytes for the purposes of default construction, and it uses high-level copy/move operation (that may invoke object's copy/move constructor) in order to relocate an element, so in any case an element can correctly manage its internal state. Also you have to be careful with TArray::SetSize - it may lead to memory leaks, because it does not invoke destructors when the given function is supposed to remove some elements (in case if new size is less than the initial size). IIRC, 227i UScript dynamic arrays of strings had huge memory leaks when performing array downsizing, and it's not hard to guess where that error comes from.
This also causes some linker errors
....
which is weird, because it didn't before the untemplate change...
Some (not mentioned) linker errors after some (not mentioned) changes in program... M-m-m, OK, good luck with fixing.
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Is there a proper fix for TArray linkage?

Post by han »

A part of program, that does not directly invoke UE functions, may store its data in any suitable containers and use libraries that have no any relationship to UE.
This tends to be usually not the case.
zero-initialization of object's memory must be sufficient for its default construction
I haven't yet encountered any situation in UE1 where this wasn't the case.
bitwise copy of object's memory must be sufficient for moving the object to a new memory location.
This isn't a huge issue, this would just be an issue when you allocate subobjects which would point back to the object inside your array, and i haven't encountered this situation in UE1.

It seems a bit of a wild mix on TArray, whether a constructor/destructor is called on insert/remove, and is probably worth to clean up a bit.
IIRC, 227i UScript dynamic arrays of strings had huge memory leaks when performing array downsizing, and it's not hard to guess where that error comes from.
UObjects + TArray are certainly a pain in the ass, and there are many troubles associated with it. Especially the "template" default object for classes where these arrays are not empty, the property import/export functions (e.g. if you set EditPackages defprops inside a UEditorEngine subclass, which is a TArray those will give you hell..). So there is certainly a lot of work involved to properly handle these things...
This also causes some linker errors
....
which is weird, because it didn't before the untemplate change...
Some (not mentioned) linker errors after some (not mentioned) changes in program... M-m-m, OK, good luck with fixing.
[/quote]
My crystal ball says you didn't remove the ENGINE_API macro on FSoundData, FMipMapBase and FMipMap... ;)
HX on Mod DB. Revision on Steam. Löffels on Patreon.
User avatar
[]KAOS[]Casey
OldUnreal Member
Posts: 4497
Joined: Sun Aug 07, 2011 4:22 am
Location: over there

Re: Is there a proper fix for TArray linkage?

Post by []KAOS[]Casey »

Except I did remove those. And the linker errors are one of the many mentioned already here, so I thought it was unnecessary to even paste them

edit: this is the untemplate.h that I was given www.oldunreal.com/cgi-bin/nopaste/?19

Previously I just used 227i public headers untemplate.h

Pretty much just going with the default plan of VC6, because unless we can fenagle the compiler to use the symbols to match what the .lib has, no amount of crappity smacking around will fix it.


edit2: FSoundData isn't even used in my code so why would changing that be necessary?
Last edited by []KAOS[]Casey on Thu Sep 08, 2016 4:15 pm, edited 1 time in total.
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Is there a proper fix for TArray linkage?

Post by han »

You could try adding

Code: Select all

template class TArray;
template class TArray;
At the end of UnTemplate.h as MK suggested.
HX on Mod DB. Revision on Steam. Löffels on Patreon.
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: Is there a proper fix for TArray linkage?

Post by Masterkent »

A part of program, that does not directly invoke UE functions, may store its data in any suitable containers and use libraries that have no any relationship to UE.
This tends to be usually not the case.
I have no idea what you're implementing there, but I can imagine a mod that would implement some sort of database in C++, and the only part that would really do something with UE functions/classes would be the interface of queries to that database. Implementation of the database itself can be completely independent from UE.
You could try adding

Code: Select all

template class TArray;
template class TArray;
At the end of UnTemplate.h as MK suggested.
That shouldn't be necessary after removal of the dllimport specifier. The compiler should implicitly instantiate everything that needs instantiation unless you either explicitly suppress such instantiation or hide the templated definition of a function from the compiler:
[temp.inst] / 2:

Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist;
[temp] / 6:

A function template, member function of a class template, variable template, or static data member of a class template shall be defined in every translation unit in which it is implicitly instantiated (14.7.1) unless the corresponding specialization is explicitly instantiated (14.7.2) in some translation unit; no diagnostic is required.
Last edited by Masterkent on Thu Sep 08, 2016 9:15 pm, edited 1 time in total.
User avatar
[]KAOS[]Casey
OldUnreal Member
Posts: 4497
Joined: Sun Aug 07, 2011 4:22 am
Location: over there

Re: Is there a proper fix for TArray linkage?

Post by []KAOS[]Casey »

forward declaring the TArray caused a linker error, the other appears to have no effect since TARRAY is used in untemplate.h

removing ENGINE_API adds linker errors to TLazyArray -

The additions with ENGINE_API being removed, or the forward declaration of TArray add these linker errors.

Code: Select all

1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TLazyArray::TLazyArray(class TLazyArray const &)" (__imp_??0?$TLazyArray@E@@QAE@ABV0@@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TLazyArray::~TLazyArray(void)" (__imp_??1?$TLazyArray@E@@QAE@XZ)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TLazyArray::TLazyArray(int)" (__imp_??0?$TLazyArray@E@@QAE@H@Z)
one of my linker errors was caused by SetSize not existing in UT99 -- looks like I jumped the gun on using 227i public header originally. I fixed up UT99's original header now. All I had to do was add a few "Typename" declarations.

I've currently reduced it down to

Code: Select all

FMipmap *M = new FMipmap( 0, 0,0); 
M->DataArray(0);
where accessing DataArray(0) causes the linker error.

Code: Select all

1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: unsigned char & __thiscall TArray::operator()(int)" (__imp_??R?$TArray@E@@QAEAAEH@Z)
1>..\..\System\TextureMerger.dll : fatal error LNK1120: 1 unresolved externals
I'll also need to figure out how to reimplement or workaround SetSize being missing.
Last edited by []KAOS[]Casey on Fri Sep 09, 2016 1:03 am, edited 1 time in total.
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: Is there a proper fix for TArray linkage?

Post by Masterkent »

forward declaring the TArray caused a linker error
What do you mean by forward declaring the TArray? The language rules forbid declarations like

Code: Select all

class TArray;
You can forward-declare the entire template

Code: Select all

template 
    class TArray;
but not its specializations.

If you're referring to explicit instantiation of TArray

Code: Select all

template class TArray;
then it could make sense only in DLL that is supposed to export member functions of TArray that can later might be imported by other module.

When you tell the compiler that some function shall be imported from a DLL, you obviously need to ensure that some DLL really exports such a function. Otherwise, where should the linker obtain that function from?

Since it is impossible to export the entire template, you can export only a finite set of functions that can be generated from the template. The presence of generic definition of a member function like TArray::Remove won't magically make all its possible specializations exported. You can instantiate TArray with billions of types - TArray, TArray, TArray, TArray, ..., TArray, and so on, and every such a specialization TArray will have its own distinct member function TArray::Remove. Hence we have a reasonable question: what set of functions should be exported? Obviously, the compiler needs some hint regarding what set of functions we need.

However, all these things with exporting/importing may be unnecessary (you should know better the specifics of the UE API, because you were working with it; I'm just speaking about the general theory - templates & DLLs). Then you could remove dllimport specifiers and rely on implicit instantiation of templates from headers.
The additions with ENGINE_API being removed, or the forward declaration of TArray add these linker errors.

Code: Select all

1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TLazyArray::TLazyArray(class TLazyArray const &)" (__imp_??0?$TLazyArray@E@@QAE@ABV0@@Z)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TLazyArray::~TLazyArray(void)" (__imp_??1?$TLazyArray@E@@QAE@XZ)
1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall TLazyArray::TLazyArray(int)" (__imp_??0?$TLazyArray@E@@QAE@H@Z)
These messages clearly indicate that dllimport specifier is present and applied. The linker could previously omit issuance of these errors after detection of other errors.
All I had to do was add a few "Typename" declarations.
What is a typename declaration?
I've currently reduced it down to

Code: Select all

FMipmap *M = new FMipmap( 0, 0,0); 
M->DataArray(0);
where accessing DataArray(0) causes the linker error.

Code: Select all

1>TextureMergerMain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: unsigned char & __thiscall TArray::operator()(int)" (__imp_??R?$TArray@E@@QAEAAEH@Z)
1>..\..\System\TextureMerger.dll : fatal error LNK1120: 1 unresolved externals
The same history - the compiler sees that TArray::operator() is odr-used, but does not instantiate the function definition from what you have in your header because of dllimport specifier. The linker fails to find the given function in any DLL and issues an error message.
Last edited by Masterkent on Fri Sep 09, 2016 7:18 am, edited 1 time in total.
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Is there a proper fix for TArray linkage?

Post by han »

Code: Select all

Result->Mips(i).Clear();
Result->Mips(i).DataArray.SetSize(offset);
to...

Code: Select all

Result->Mips(i).Clear();
Result->Mips(i).DataArray.Add(offset);
HX on Mod DB. Revision on Steam. Löffels on Patreon.
Post Reply

Return to “C++ Native Mods for UE1”