Managed and unmanaged code error C3699 - c#

I am working on a game which uses C# and C++. Classes for models are written in C# and levels structure is stored in XML files. When I want read it in C++ and want to build project I have this strange error and I don't where to find some bugs.
Error 1 error C3699: '*' : cannot use this indirection on type 'Cadet::XMLReader::Models::Obstacle' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xmemory0 527 1 Cadet.Game
These kind of errors are in xmemory0 and list files? what they are? and it happend only for Obstacle class, the rest are fine.
Here it is part of the code
void SetupObstacles(std::list<Cadet::Game::Entities::Obstacle> &obstacles)
{
int size = CurrentLevel->Obstacles->Length;
Cadet::XMLReader::Models::Obstacle^ currentObstacle;
}

It looks like Cadet::Game::Entities::Obstacle is a managed class (since you've declared currentObstacle as a reference with ^). If that's the case, you can't directly store managed objects in STL containers like std::list<>.
It's hard to say what to do next w/o more context, but one possible fix would be to change your SetupObstacles method:
void SetupObstacles(System::Collections::Generic::List<Cadet::Game::Entities::Obstacle>^ obstacles)
{ ... }

Do you have a pointer to an Obstacle somewhere?
The help on this error suggests that some types (such as trivial properties) cannot have a reference type--you can't have a pointer to it. Try using ^ instead.

Related

How to know if a particular script doesn't exist in the project so it doesn't generate any error in Unity

I have a line of script which gets a class refrence from third party script(NGUI package):
UIEventListener.Get(this.gameObject).onClick += expiryDateSettingsUIController.ActiveDeactiveUICaller;
The UIEventListener class belongs to NGUI package. My problem is that I don't want to show any error if that particular class doesn't exists. How can I do that?. If the class is not available then it is throwing compiler error and won't allowing me to build the exe.
You can use GetType() to reflect the class you are looking for:
Type mType = Type.GetType("UIEventListener");
if(mType != null)
{
UIEventListener.Get(this.gameObject).onClick += expiryDateSettingsUIController.ActiveDeactiveUICaller;
}
C# is a compiled language, so before you can run any code, it needs to be error-free. An absent class is a very serious compilation error. There is no way (in Unity or otherwise) that you can achieve the behavior you're asking for.
However, you can use conditional compilation. Conditional compilation, as the name suggests, is when you strip pieces of code out during compilation, so those pieces are never compiled and no compilation errors will be encountered for those. Wrap your code in #if/#endif like below:
#if WITH_NGUI
UIEventListener.Get(this.gameObject).onClick += expiryDateSettingsUIController.ActiveDeactiveUICaller;
#endif
Then, to let this code compile, you will need to define the WITH_NGUI conditional compilation symbol. In Unity, you can go to Player Settings, and there will be a box named Scripting Define Symbols where you can type in as many symbols as you like. Type WITH_NGUI into that box, and the code will compile. When you don't have NGUI available, simply remove the symbol and the code won't compile any more.
This isn't a nice thing to do though. You've been warned.
EDIT: You could also use reflection to access classes which may be absent from your build, but that's way more trouble than it's worth.

Marshalling Microsoft.VisualBasic.Collection to COM

I have a C# class that has a property(name is List) of type Microsoft.VisualBasic.Collection. We need to exposed this property to COM. For that, I was writing an interface for my class such that the property would marshaled as of UnmanagedType.IDispatch.
Something like this:
[DispId(0x68030000)]
Collection List { [DispId(0x68030000)] [return: MarshalAs(UnmanagedType.IDispatch)] get; }
This piece of code was earlier in VB and was being used by C++ as tye VT_DISPATCH. However, while building the C# library, I get the following error:
C:\Program Files
(x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(4335,5):
error MSB3212: The assembly "Name.dll" could not be converted to a
type library. Type library exporter encountered an error while
processing 'Namespace.InterfaceName.get_List(#0), ProjectName'. Error:
Error loading type library/DLL.
I read through few of the posts online which suggested that such errors might cause because of repetitive GUIDs. But that is not the case. I tried with multiple GUIDs. I don't feel this is an issue with any other attribute that I had set on my Interface since, I am able to marshal other properties and function calls ( some of them use primitive types and others use custom classes) successfully.
This is how it is consumed in the consuming C++ application:
LPDISPATCH result;
InvokeHelper(0x68030000, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL);
return result;
This has become a go live issue with the client and I really do not have much time to continue investigation since this is due tomorrow.
Appreciate any help!
I don't think Microsoft.VisualBasic.Collection is COM-visible. Therefore, you cannot use this type as a return value or parameter in a COM class or interface. However, ICollection (which Microsoft.VisualBasic.Collection implements) is COM visible. If that would suit your purposes, use that as the type of your property rather than Microsoft.VisualBasic.Collection.

Convert Object to an array of Ushort in c#

I'm fairly new to C# but i'm looking to convert an object to an array of unsigned shorts. The original data is an array of WORD's (numerical value WORD) passed as an object. I've attempted the following but keep getting an error.
object temp = Agent.Port("PumpPressure1_01").Value;
ushort[] PP1_01 = ((IEnumerable)temp).Cast<object>()
.Select(x => x == null ? x.ToUshort())
.ToArray();
When I run this I get the following error:
'System.Collections.Generic.IEnumerable<T>' requires '1' type arguments.
The namespaces I used when I get the above error are:
using System.Linq;
using System.Text; // Don't think this is required but added it in case
If I add the following namespaces:
using System.Collections;
using System.Collections.Generic;
I get the following error.
'System.Linq.ParalleIEnumerable.Select<TTSource,TResult>()' is not supported by the language
I'm sure this is an obvious issue but I've been hunting the net for a while and can't find a solution. My best guess is that the Select function isn't correct as this was originally designed to convert an object to an array of strings.
Any help would be great.
Thanks
IEnumerable is a generic interface, so you have to declare the datatype you are using...
To be honest though, I would want to check what that call to
object temp = Agent.Port("PumpPressure1_01").Value;
is actually returning - by inspecting it in the debugger... If it is simply returning a reference to an array of a numeric type, you should be able to simply cast it. What you are doing though is trying to cast each individual item within the array - I suspect that's not what you should be doing - which would be casting the array itself.
Can you give us any API documentation for the Port method on the Agent object so I can see what it is meant to return? Can you try the inspection and see what that gives you?
Why you casting to IEnumerable and then casting it back to object if your temp variable is already of type object?
Also IEnumerable<T> is a generic interface and must specify exact type (as exception also says to you). If you have an array of integers and you want to work with them it should be IEnumerable<int>
Thanks for all the help and feedback.
Unfortunately I was't paying enough attention to the warnings that was posted which seems to be causing the issue.
Warning: Reference to type 'System.Func '2' claims it is defined in 'c:\Windows\Microsoft.NET\Framework64\v2.0.50727mscorlib.dll'. but it could not be found
It seems that there is some issue with the .NET reference. I have another VM which I tested the following solution on and it seemed to work without issue. Looks like I'll have to reinstall the software package to get it to work on the VM i want to use.
The software package I'm using is a custom package that uses C# to build solutions with prebuilt classes made to look like plug and play blocks. You can connect the blocks together drawings lines from one input/output of a block to another. You can then build C# code inside the blocks. Basically c# for dummy's like me..
Example of the blocks:
As for the code, I did have to make some changes as follows but now works a treat. Agent.Port("PumpPressure1_01").Value.RawValue is used to reference the particular ports on the block.
object temp = (object)Agent.Port("PumpPressure1_01").Value.RawValue;
UInt16[] PP1_01 = ((System.Collections.IEnumerable)temp).Cast<object>()
.Select(x => Convert.ToUInt16(x))
.ToArray();
foreach(UInt16 x in PP1_01)
{
Agent.LogDebug("values: " + x.ToString());
}
Again, thanks for all the help. Just need to resolve the issue with the library reference now.

C#: Unexpected character '$'

I decompiled a C# assembly using ILSpy. Opened it as a project in VC.
A small portion of the code throws errors that I don't know how to fix. Here's the code:
public static class CoroutineUtils
{
[DebuggerHidden]
public static IEnumerator WaitForRealSeconds(float time)
{
CoroutineUtils.<WaitForRealSeconds>c__Iterator2F <WaitForRealSeconds>c__Iterator2F = new CoroutineUtils.<WaitForRealSeconds>c__Iterator2F();
<WaitForRealSeconds>c__Iterator2F.time = time;
<WaitForRealSeconds>c__Iterator2F.<$>time = time;
return <WaitForRealSeconds>c__Iterator2F;
}
}
And here's the error: Unexpected character '$' (at line 8 in this case).
And if I open the .cs file in which the error appears, the compiler starts throwing a dozen more errors like Identifier expected at line 6 (right after "CoroutineUtils.")
Don't know what to do.
You can't just copy/paste decompiled code and be sure it will work. Compiler can use identifiers that are not valid in C# code but are valid in IL. It happens mostly for compiler generated code - automatic properties, anonymous types, iterators and async/await converted to state machines, etc. That's the case here.
It's really hard to say what the code is suppose to do, so it's really hard to say how to fix it.

Instantiating C# Classes in Lua

I am writing a scripting engine for my game using the LuaInterface library. I am getting an error when attempting to instantiate the class in Lua. The error is:
"./Scripts/sv_worldgen.lua:2: attempt to call global 'Campfire' (a string value)"
Where sv_worldgen.lua is (in entirety):
function GenerateChunk(worldChunk, chunkGridPosition)
tf = Campfire()
tf:SetPosition(chunkGridPosition)
end
Campfire is a class in C#, and appears to be exposed to lua as per the CLRPackage example and of course the LuaInterface Reference. I cannot seem to get around this error, and I have done due diligence of searching. The only other behavior of the script I can manage throws a similar error, but where it is "(a table value)". What am I doing wrong? Thank you in advance!
I tried explicitly doing Campfire._ctor(), but _ctor() is a string value.
This was resolved by using CLRPackage and using it to first load the assembly.
//Lua
JASG = CLRPackage("JASG", "JASG")
Then and only then can you link the classname to the actual C# class using (this must be done before trying to access it in Lua):
//Lua
Campfire=JASG.Campfire;
and then normal instantiation can occur by
//Lua
cf = Campfire()

Categories