Did IL2CPP process change between 2019 and 2020?

We have not seen any notes about changes to the IL2CPP process in Unity 2020 and are trying to figure out an issue with our project after updating to Unity 2020.

We are in the process of migrating a project for Microsoft HoloLens 2 from Unity 2019.4.23f1 to Unity 2020.3.41f1. We are seeing an issue compiling our visual studio solution that breaks our builds and is not reproducible in older versions of unity. We have a custom assembly .dll that has shown no issues until this update. The project still functions in the editor. When we attempt to build, we are successful in creating our visual studio solution. When we try to build our visual studio solution for Release targetting ARM64 (as required for most HoloLens 2 builds) we encounter an error related to our custom assembly that states that there is an invalid integer constant expression. The code referred to is here:

if FORCE_PINVOKE_INTERNAL || FORCE_PINVOKE_**Internal_INTERNAL

IL2CPP_EXTERN_C int32_t DEFAULT_CALL DnsQuery_W(char*, int32_t, int32_t, int32_t, intptr_t, int32_t);

endif

When checking our previous .cpp from the same DLL that was generated from the Unity 2019 project this line of code is not present, instead we see

if FORCE_PINVOKE_INTERNAL

IL2CPP_EXTERN_C int32_t DEFAULT_CALL DnsQuery_W(char*, int32_t, int32_t, int32_t, intptr_t, int32_t);

endif

Looking for any ideas on where to look to investigate this issue. As noted, the DLL functions perfectly in Unity 2019, and also in the Editor for 2020, so mostly curious if something has changed in the IL2CPP generation process for Unity 2020 that we have missed.

This is not the forum for IL2CPP questions! Doubt that Visual Studio is the source of your problem :p

I have no answer to your question, but if somebody does have, it would be @JoshPeterson

1 Like

[quote=“Baste”, post:2, topic: 899174]
This is not the forum for IL2CPP questions! Doubt that Visual Studio is the source of your problem :stuck_out_tongue:

I have no answer to your question, but if somebody does have, it would be @JoshPeterson
[/quote]

Where should I direct this question?

Maybe the Windows Platform sub-forum? I can move your post if you wish.

Josh tagged above though would likely be the person who'd have your answers. :)

1 Like

So this is a bit silly, but since there's no subforum for "hey, we have technical questions regarding the compilation/build pipeline that shouldn't get drowned in 'duh how for loops work'", the best bet for these kinds of things is generally to ask in Experimental Scripting Previews.

Please, thank you

1 Like

Done.

Can you show the full compiler error message and the source code it's complaining about in [ CODE ] tags?

#if FORCE_PINVOKE_INTERNAL || FORCE_PINVOKE_**Internal_INTERNAL
IL2CPP_EXTERN_C int32_t DEFAULT_CALL DnsQuery_W(char**, int32_t, int32_t, int32_t, intptr_t*, int32_t);
#endif

The GameAssembly.lib failure is something we are ignoring because the file doesn't finish being made due to this exception and doesn't exist, so it can't be opened.

Do you have source code for this DLL? Can you show how the "DnsQuery_W" method is declared in C#?

Yes, have already requested it from the team that compiled it. It may take a little while before I can provide it.

Here is the declaration of method:

[DllImport("**Internal", EntryPoint = "DnsQuery_W", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
private static extern int DnsQuery([MarshalAs(UnmanagedType.VBByRefStr)]ref string pszName, QueryTypes wType, QueryOptions options, int aipServers, ref IntPtr ppQueryResults, int pReserved);

Okay, so this is definitely a bug in IL2CPP. If you could report a bug, we would be able to address it.

That said, you should be able to work around it on your own. There is a typo in that signature you pasted. It should be this:

[DllImport("__Internal", EntryPoint = "DnsQuery_W", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
private static extern int DnsQuery([MarshalAs(UnmanagedType.VBByRefStr)]ref string pszName, QueryTypes wType, QueryOptions options, int aipServers, ref IntPtr ppQueryResults, int pReserved);

(Notice "__Internal" instead of "**Internal"). However, I'm not sure if this function is supported on UWP and if it's not, this change will make it so you get a linker error about it being an unresolved external symbol. Alternatively, you could remove that function since it would have thrown a DllNotFoundException previously anyway due to that typo.

1 Like

Thank you, we will make this change and recompile the assembly and test.

Given this DLL has compiled just fine to UWP with Unity 2019.4.x, can you please explain why you consider **Internal a typo? It would be helpful to explain to the team that compiled this DLL for my team, since it compiled just fine in all previous versions of Unity we have worked with. We are currently using this DLL in an app published on the Microsoft Store and have not encountered any issues until the upgrade to Unity 2020, as noted in the original post.

I will open a bug report as well.

So the reason it doesn't compile because it's a bug in IL2CPP. It accidentally does not expect the DLL name to contain characters that are not valid C++ identifiers other that '.' and '-', and "*" is not a valid identifier in C++. If this worked correctly, it would just replace the invalid characters with something else instead of triggering a compilation error.

The reason I am saying it is a typo because it looks very similar to the "__Internal" keyword that IL2CPP supports in the [DllImport] attribute. It has a special meaning: functions that are annotated that way will be resolved by the linker at build time, rather than loaded at runtime. "Internal", on the other hand, has no special meaning, so unless you have a native plugin that is named "Internal.dll", it makes no sense. "**Internal.dll" sounds an unlikely file name so that's why I thought it was a typo.

As for the DLL working fine before: perhaps this function is just never called? If it's never called, it will never try to load the non-existing DLL and will never throw an exception.

This function is used in the application. In my initial post, you can see that this function is compiled when building from a solution created in Unity 2019 and shows up as

if FORCE_PINVOKE_INTERNAL

IL2CPP_EXTERN_C int32_t DEFAULT_CALL DnsQuery_W(char*, int32_t, int32_t, int32_t, intptr_t, int32_t);

endif

That's what made this confusing and why it seemed so strange that compiling a Visual Studio Solution from 2019 works fine and results in the above code, but compiling a visual studio solution from 2020 results in the "typo" you are referring to. Thank you for the additional information.

Just because it is compiled doesn't mean it's actually called at runtime.

[quote=“Tautvydas-Zilys”, post:15, topic: 899174]
“**Internal”, on the other hand, has no special meaning, so unless you have a native plugin that is named “**Internal.dll”, it makes no sense. “**Internal.dll” sounds an unlikely file name so that’s why I thought it was a typo.
[/quote]
It turns out the docs for P/Invoke on UWP actually do say to use “**Internal”
https://docs.unity3d.com/2020.3/Documentation/Manual/windowsstore-plugins-il2cpp.html
https://docs.unity3d.com/2022.2/Documentation/Manual/windowsstore-plugins-il2cpp.html

[quote=“Anthiese”, post:18, topic: 899174]
It turns out the docs for P/Invoke on UWP actually do say to use “**Internal”
https://docs.unity3d.com/2020.3/Documentation/Manual/windowsstore-plugins-il2cpp.html
https://docs.unity3d.com/2022.2/Documentation/Manual/windowsstore-plugins-il2cpp.html
[/quote]

Oh geez, thank you for pointing that out. The code samples look correct but the text section is mangled. I’ll make sure we fix this. EDIT: issue tracker link: https://issuetracker.unity3d.com/issues/typo-in-uwp-documentation

1 Like