Google gflags library in visual studio: Can't inspect FLAGS_ variables - c++

I have built google gflags in windows using visual studio 2015.
The built is a Debug build (so Program Database (/Zi) is set) and I'm stepping through the gflags_unittest_main.cc.
The unit test passes successfully. However, while debugging I can't see the contents of the FLAGS_## variables.
For example, line 1515 of gflags_unittest_main.cc is
FLAGS_changed_bool2 = true;
I can't see the value of FLAGS_changed_bool2 in the watch window. I have tried adding the google:: and gflags:: namespaces in front of FLAGS_changed_bool2 but it just says identifier is undefined. Here it says you can access these flags just as a normal variables.
Why can't I see the values of these variables while debugging? What can I do to see them? maybe some build option?
I'm trying to understand the code of another open source library that uses gflags and has hundreds of FLAGS_ variables. Not being able to see the contents of these variables makes the task more difficult.

I found a workaround for this. Each of the FLAGS_ variables are created inside namespaces which include a short identifier for the type (see DEFINE_VARIABLE macro in gflags.h). For example, fLI for integer, fLB for bool, fLS for String, etc.
So if I add to the watch window the following:
fLB::FLAGS_changed_bool2
fLI64::FLAGS_this_is_an_int64_variable
I can see their values.
The DEFINE_VARIABLE macro adds a using statement
using fL##shorttype::FLAGS_##name
after the definition of the variable inside the fL##shorttype, which allows the user code to refer to FLAGS_##name directly. However the Visual Studio debugger ignores this using and needs the namespace for each of these variables. I guess the next question is how to get visual studio to use this using statements, so that I can hover my mouse pointer over the variable a see its value.

Related

In Unity3d test scripts, how do I call a static function from another class?

I have two files in a Unity3d project. One is a test script that runs in edit mode. The other is a single class with static functions that I'd like to call from the test scripts.
here's my test script:
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
public class NewTestScript
{
[Test]
public void TestAnotherStaticFunction()
{
int a = NewBehaviourScript.FunctionUnderTest(1);
int b = 1;
// Use the Assert class to test conditions.
Assert.IsTrue(a == b);
}
}
here's my function under test:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
/// <summary>
/// the stupidest function in the world,
/// used to verify tests.
/// </summary>
public static int FunctionUnderTest(int a)
{
return a;
}
}
This gives me the error from the Unity compiler (I'm not building outside of Unity):
Assets/TestS/NewTestScript.cs(12,17): error CS0103: The name `NewBehaviourScript' does not exist in the current context
These are running in edit-mode.
I've tried adding and removing the SuperTestNameSpace namespace from the function under test and the calling code.
I've attempted adding/removing files from the .asmdef file that was autogenerated by unity, although this usually leads to other compile errors.
My previous unit test experience is largely in Visual Studio or VSCode, and I'm trying to get my unity3d test experience to match my prior test environment experiences.
Is there a fundamentally limited functionality in the edit-mode tests, or am I missing something stupid?
Further elaboration on the assemblies involved. It looks like there are two assemblies at play here: Assembly-CSharp.dll contains my code under test and TestS.dll contains my testing code. I believe my questions boils down to: how do I add a reference from the TestS.dll assembly to the Assembly-CSharp.dll. I'd know how to do this in Visual Studio (either via the context menu in VS or directly editing the csproj file), however I don't see how to do it in Unity3d. Any edit I make to the csproj file is frequently overwritten by unity, and while there is a 'references' section in the inspector (see picture) I can't add Assembly-CSharp.dll as a reference.
These are the inspector settings for TestS.asmdef. While there's an option to add references, I can't add a reference to Assembly-CSharp.dll, which is where my code-under-test lives.
Ok, I figured this out. There were two things going on:
Editor tests need to be underneath a folder called editor. It's really annoying that the unity editor doesn't do this for you.
You need to have an assembly definition for the code under test and add a reference from the test code to the newly created assembly definition. This must be done in the Unity editor UI.
by default, unity adds your script code to an assembly called Assembly-CSharp.dll, and, for reasons unknown, this assembly isn't referenced by my edit mode test code. I'm not sure if this is a bug in Unity or if it's by design, but explicitly creating and referencing the assembly definition has cleared things up.
The main issue is currently you are trying to call the
NewBehaviourScript(1);
constructor which does not exist...
instead of the method
using SuperTestNameSpace;
//...
NewBehaviourScript.FunctionUnderTest(1);
or alternatively with the namespace in the call directly
SuperTestNameSpace.NewBehaviourScript.FunctionUnderTest(1);
Also make sure the filename matches exactly the class name. So in your case it should be
NewBehaviourScript.cs
Note that the .cs is not printed by Unity in the Project view so there it should say NewBehaviourScript.
Why does it not compile with the using SuperTestNameSpace;? What is the error?
If that exception
Assets/TestS/NewTestScript.cs(14,17): error CS0103: The name `NewBehaviourScript' does not exist in the current context
is only shown in VisualStudio but the script compiling fine in Unity especially after adding a new script it helps to simply close and restart VS.
In some cases it also helps to close Unity and VS, remove all files and folders except Assets and ProjectSettings (and if you are under version control anything that belongs to it like e.g. .git, .gitignore, .gitattributes etc) in particular delete the Library, .vs folder and all .csproj and .sln files.
Than open Unity again and let it recompile everything.
Make sure the file that contains your NewBehaviourScript class IS NOT inside an Editor folder.
Move both the scripts in the Assets (root) folder and try again.

How can I debug a C++ DLL function, called from VBA, using Visual Studio

I have written a DLL function in C++, which I am calling from VBA (Excel).
How can I setup the Visual Studio properties to allow me to debug the function? I have tried specifying Excel, but that doesn’t seem to work.
You have two choices: "direct debug", or "attach".
I strongly prefer the "direct debug" approach for a long list of reasons omitted from here.
There are steps required on both the DLL and Excel/VBA sides, your posting is unclear if all of those steps are addressed.
There are variations on the following:
1) In VS, depending on the version, enter Project Settings, or Project Properties, or equivalent, in the "Debug (not release) Target", go to the Debug or Debugging settings. :
a) There will be an field called "Executable for debugging session", or "command", or something like that depending on VS ver. Here, enter the full path of your Excel exe
b) Optionally, if the same "test spread sheet" is used frequently, enter the full path of your xls (or whatever) in the field called "Command argument", or "program argument" or as in your VS ver.
You may need to surround this with double quotes (e.g. if there are spaces in your path/file names).
c) You can also set the output of your project to a Dir that is "addin helpful", such as a Dir called AddIn (c.f. having the DLL end up in Debug (or Release) Dirs)
... it is assumed that your DLL has all the bits required to export the functions, with the project being of type DLL, plus any DLLEXPORT and compiler directives, etc etc.
... the specifics of the DLLEXPORT settings (and related compiler switches) and Calling Convention will determine many things ... it is assumed you have done all that correctly and consistently (and especially consistently with what the Excel-side is expecting).
... your DLL may or may not have a DLL_Main, if it does, more discussion is required.
2) Before anything else, be sure to have created the Excel-side "interface" for your DLL, ie. the "Add-In". This can be either via .xla, or via .xll. I strongly suggest the .xla route as your first approach.
See the Excel help files etc for creating the .xla
Then, in your XLA's VBA Module(s), declare the functions/subs etc from your DLL. For example, if you have a DLL called Add2_DLL.dll, which contains an exported function "add2_pho_xl", then:
Public Declare Function Add2_Pho_XX Lib "E:\EclipseWorkSpace\Add2_DLL\Debug\Add2_DLL.dll" _
Alias "add2_pho_xl" (A As Double, B As Double) As Double
I have used the Alias approach here, for reasons required below.
In many instances, this declaration can be used directly as User Defined Function (UDF) in your sheets, etc. However, for a vast number of cases, you will need to create a VBA "spinner" function/sub that creates the "ultimate" UDF, and relies on this direct entry function (see below). This is also a very long story, but necessary where more complex matters are required (arrays, variants, etc etc).
NOTICE:
a) the DLL's full path is required unless special steps have been taken. If your Addin is for general distribution ... a much longer discussion is required.
b) the Alias must be the EXACT entry name of the function in your DLL. If you view near the end of the DLL (or .Def) files, and unless you set your DLL modules as Private, those will show the entry names expected on the DLL side.
In this example, the entry name is NOT "decorated" due to the choices in the Calling Convention and compiler switches, but it could look something like
"_add2_pho_xl_#08" etc depending your choices.
... in any case, you must use whatever the DLL has.
3) Once both the .xla and dll exist (it is best if they are in the same Dir), Excel must be "told" about the Add-In. The easiest approach is Excel/Tools/Addins, but there are various strategies for "registering" DLL functions.
4) CRUCIALLY, the argument list properties/declarations MUST BE CONGRUENT with BOTH those in your DLL and the Calling Convention. Three (of many possible) examples of "issues" are,
(i) A Boolean on the VBA-side is two-bytes, if the Bool/Logical on your DLL side is 1-byte, then the Debug will fail, since the two sides "cannot connect" properly.
(ii) Strings ... this can be a very long story. It depends if sent ByVal or ByRef, it depends if the DLL side has "hidden length" Args, etc. etc. Remember, VBA uses COM/OLE VBStrings, which have their own can of worms.
(iii) Variants/Objects: these require a tome onto themselves
5) If ALL (and likely more) of the above have gone well, then in VS set your break points, if required, and "Go" or "Start" the debug (depending on VS ver, etc.). This should launch Excel, and if you also set the target xls, it will launch too. Go to the cell(s) where you addin function (e.g. =add2_pho_XX(A1, B1) ) resides, and execute the cell (sometimes using the "fx" menu item is useful, but there are other ways also).
Some hints:
a) if the func execution crashes/hangs etc Excel and does not even arrive back to the VS side, then likely there is a Arg list conflict (e.g. you are passing a Double to an Int or a million other possibilities), or Calling Convention conflict, etc.
b) In general, you may (while in the VS debug session) simultaneously perform a VBA debug session. That is, after starting the VS bebug, entre the VBA IDE, and set break points in VBA UDF's, if a "spinner" UDF's have been created. For example, a VBA UDF that relies also on the DLL's function.
Private Function Add2_Pho( FirstNum as Double, SecondNum as Double, Optional lMakeRed as Variant) As Variant
'
'
Add2_Pho = Add2_Pho_XX( FirstNum, SecondNum ) ' this is the actual DLL func accessed via Delcare above
'
If( IsMissing(lMakeRed) ) Then
Else
If( cBool(lMakeRed) ) Then
If( Add2_Pho < 0 ) Then
'
' ' make the result Red, or something
'
End If
End If
End If
'
'
End Function
... here, setting a break point at the first line can be helpful to see if the UDF is even entered on the VBA side. If it is, click Continue in VBA, and see if it makes it to the VS side, if not, check Args, Calling Convention, etc again, etc etc
c) If the cell's content are #Value or some other unexpected result, then at least the UDF is "recognised" but not functioning correctly, either due to sheet->VBA issues, or VBA-> DLL issues, or after the return DLL-> VBA
d) Save often! and Use the VBA IDE's Debug/ Compile VBA Project before running anything just make sure VBA internal consistency.
e) Also, if you are using VBA/XLA's, then get a copy of CleanProject (VBA can mess up its internals sometimes, and this Tool will be a life saver)
Please make sure that Debug mode is the active mode.
How to debug your DLL with Excel/VBA

How do I use DTE.ExecuteCommand("Edit.GoToDefinition") in a VS2010 C++ macro?

I recorded a macro that includes a keypress of F12 (Go To Definition), but the recording omits the second parameter that is passed to DTE.ExecuteCommand, causing the macro to crash during execution. Presumably the second arg is the name of the function I want to find, but I can't figure out how to get and pass the value. If I select the function or method name (but not the args or the class prefix), I can use DTE.ActiveDocument.Selection.Text.ToString to pass the selection, but instead of jumping to the definition, it returns the both the .h file and the .cpp file in the Find Symbol Results window.
(And I'm not sure selection is really what I want, though I could probably get the macro to select the "right thing" if that's the way to go. Is there any way to see what F12 is passing, just to see what it looks like? Or better yet, find out what programmatic object F12 is passing?
Vs2010 Pro
Turns out running the same command via IVsUIShell works:
Dim cmd As EnvDTE.Command
Dim shell As Microsoft.VisualStudio.Shell.Interop.IVsUIShell
Dim arg As Object
Dim guid As System.Guid
Dim serviceProvider As System.IServiceProvider
serviceProvider = New Microsoft.VisualStudio.Shell.ServiceProvider(CType(DTE, Microsoft.VisualStudio.OLE.Interop.IServiceProvider))
shell = serviceProvider.GetService(GetType(Microsoft.VisualStudio.Shell.Interop.SVsUIShell))
cmd = DTE.Commands.Item("Edit.GoToDefinition", 0)
guid = New System.Guid(cmd.Guid)
shell.PostExecCommand(guid, cmd.ID, 0, arg)
The code works as is in Visual Commander. To run it from Visual Studio macros IDE, you need to add references to
Microsoft.VisualStudio.OLE.Interop.dll
Microsoft.VisualStudio.Shell.10.0.dll
Microsoft.VisualStudio.Shell.Interop.dll
Microsoft.VisualStudio.Shell.Interop.8.0.dll
Microsoft.VisualStudio.Shell.Interop.9.0.dll
And to add references you first need to copy these files to the Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies directory.

Including C++ headers in user mode programs built with NT DDK

So...I have a kernel mode component and a user mode component I'm putting together using the turnkey build environment of the NT DDK 7.1.0. The kernel component is all .c/.h/.rc files. The user mode component is .cpp/.c/.h/.rc files.
At first it seemed simplest to use build for both, as I saw you could modify the ./sources file of the user mode component to say something like:
TARGETNAME = MyUserModeComponent
TARGETTYPE = PROGRAM
UMTYPE = windows
UMENTRY = winmain
USE_MSVCRT = 1
That didn't seem to cause a problem and so I was pleased, until I tried to #include <string> (or <memory>, or whatever) Doesn't find that stuff:
error C1083: Cannot open include file: 'string': No such file or directory
Still, it's compiling the user mode piece with C++ language semantics. But how do I get the standard includes to work?
I don't technically need to use the DDK build tool for the user mode piece. I could make a visual studio solution. I'm a bit wary as I have bumped into other annoyances, like the fact that the DDK uses __stdcall instead of __cdecl by default... and there isn't any pragma or compiler switch to override this. You literally have to go into each declaration you care about and change it, assuming you have source to do so. :-/
I'm starting to wonder if this is just a fractal descent into "just because you CAN doesn't mean you SHOULD build user mode apps with the DDK. Here be dragons." So my question isn't just about this particular technical hurdle, but rather if I should abandon the idea of building a C++ user mode component with the DDK tools...just because the kernel component is pure C.
To build a user mode program with WINDDK you need to add some variables to your SOURCES file:
386_STDCALL=0 to use cdecl calling convention by default
USE_STL=1 to use STL
USE_NATIVE_EH=1 to add a support for exception handling
Everything else you already have.
I'll put my full SOURCES file for reference:
TARGETNAME = MyUserModeComponent
TARGETTYPE = PROGRAM
TARGETPATH = obj
UMTYPE = console
UMENTRY = main
USE_MSVCRT = 1
USE_NATIVE_EH=1
USE_STL=1
386_STDCALL=0
SOURCES= main.cpp
And main.cpp:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "bla bla bla!";
cout << s;
return 0;
}
Have fun!
Quick Answer
Abandon the idea of building user-mode components with DDK tools (although I find the concept fascinating :-P)
Your kernel mode component should be built separately from the user mode components as a matter of good practice.
Vague thoughts
Off the top of my head, and this really speaking from limited experience...there are a lot of subtle differences that can creep up if you try to mix the two together.
Using your own example of __cdecl vs __stdcall; You have two different calling conventions. _cdecl is all kernel stuff and all of the C++ methods are wrapped around in WINAPI (_stdcall) passing conventions and __stdcall will clean do auto stack clean up and expect frame pointers inserted all over the place. And if you by accident use compiler options to trigger a __fastcall, it would be a pain to debug.
You can definitely hack something together, but do you really want to keep track of that in your user-space code and build environment? UGH I say.
Unless you have very specific engineering reasons to mix the two environments, (and no a unified build experience is not a valid reason, because you can get that from a batch file called buildall.bat) I say use the separate toolchains.

Visual C++ - Throwing unhandled exception from setting forms icon?

I can compile the solution with no errors, but when I'll try to run it, I get a crash window:
An unhandled exception of type
'System.Resources.MissingManifestResourceException' occurred in mscorlib.dll
Additional information: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "<myformname>.resources" was corerctly embedded or linked into assembly "<myprojectname>" at compile time, or that all the satellite assemblies required are loaded and fully signed.
And after I press Break it throws me to the line:
this->Icon = (cli::safe_cast<System::Drawing::Icon^ >(resources->GetObject(L"$this.Icon")));
If I comment this line out, everything works just fine, but my program doesn't have icon.
Anyone else had this problem? Found a solution? I couldn't find anything clear enough for me to understand, problem is really annoying me, only solution I found was to declare my form class before any other classes, but I don't even have any other classes in my solution?
I also have only one project in this solution, ms support said something about having multiple projects, which I don't have, so it was no use either.
Take a look here :
http://www.mztools.com/articles/2005/MZ2005007.aspx
The exception is thrown because your icon cannot be located. You will probably need to compiles your resources under one .dll and put this under en-US subfolder on your project output. It did the trick for me at least. There are probably other solutions to your problem too.
Do not panic like I did. The root cause of the problem is that the compiled resource file is different from the one that is asked to load at runtime. This happens because the underlying build-script cannot detect the filename or namespace changes made after the form is created.
For example, At first we started a project named x . And our $(RootNamespace) becomes x. And we created a form named y. So our XML resource file y.resx gets compiled into x.y.resource . At this point the icon change works.
Now somehow we changed the project name or the namespace to z. But our $(RootNamespace) remains the x. While at compile-time it wrongly generates old x.y.resource, but at links-time it links z.y.resource. And at this point the icon change does not work.
It can also happen if the form is under some nested namespace which is not known in the project file.
It can be fixed by changing the compilation output of the y.resx file . It can be done by right-clicking the resource and changing the Resource Logical Name to $(RootNamespace).%(Filename).resources .
I will also make sure that ProjectName,AssemblyName and RootNamespace are the same in the .vcxproj file. Somehow if the form is declared under a nested namespace like RootNamespace.gui , then the output file of the resource should be $(RootNamespace).gui.%(Filename).resources .