How to check auto_gcroot object for nullptr - c++-cli

I want to check if my C++/Cli managed auto_gcroot is null or not. Here's how I proceeded :
auto_gcroot<RefClassA^> m_a;
if (static_cast<RefClassA^>(m_a) != nullptr)
{
.....
}
The problem is that I get an error :
'No suitable conversion from 'auto_gcroot to object^ exists'

As I said in the comments, I'm not able to reproduce this on VS2012.
However, auto_gcroot has a get method that returns the object as a plain reference. You should be able to compare that to nullptr.
msclr::auto_gcroot<String^> m_a;
if (m_a.get() != nullptr)
{
// ...
}

Related

How do I change this exception?

I'm new to Android Studio.
I'm getting
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String
com.alpha1.appname.rider.model.firebase.User.getName()' on a null
object reference.
Can anyone point me in the right direction. I can't seem to fix with the answers on the other similar questions.
\Here is the line that is producing the null pointer exception\
private void setDriverData() {
View navigationHeaderView = navigationView.getHeaderView(0);
TextView tvName = navigationHeaderView.findViewById(R.id.tvDriverName);
TextView tvStars = navigationHeaderView.findViewById(R.id.tvStars);
CircleImageView imageAvatar= navigationHeaderView.findViewById(R.id.imageAvatar);
tvName.setText(Common.currentUser.getName());
if(Common.currentUser.getRates() != null &&
!TextUtils.isEmpty(Common.currentUser.getRates()))
tvStars.setText(Common.currentUser.getRates());
if(Common.currentUser.getAvatarUrl()!=null &&
!TextUtils.isEmpty(Common.currentUser.getAvatarUrl()))
Picasso.get().load(Common.currentUser.getAvatarUrl()).into(imageAvatar);
This is the problematic line:
tvName.setText(Common.currentUser.getName());
The error message tells you that you cannot call getName of null. This means that Common.currentUser is null. Something being null means that it is not defined. Referring data members or calling methods of something that does not exist will yield this error. You can fix this issue by properly initializing Common.currentUser before that line executes, or defaulting it if it was not defined, like:
tvName.setText((Common.currentUser == null) ? "" : Common.currentUser.getName());

Invalid pointer operation when freeing TStreamAdapter

Can anyone clarify why do I get "Invalid pointer operation" when I attempt to delete TStreamAdapter? Or... how to properly free the memory from TStreamAdapter? It works, if I remove the delete but that causes a memory leak. Even if I use boost::scoped_ptr it also fails with the same error.
Note: I also tried initializing TStreamAdapter with soOwned value, same error.
The code:
HRESULT LoadFromStr(TWebBrowser* WB, const UnicodeString& HTML)
{
if (!WB->Document)
{
WB->Navigate("about:blank");
while (!WB->Document) { Application->ProcessMessages(); }
}
DelphiInterface<IHTMLDocument2> diDoc = WB->Document;
if (diDoc)
{
boost::scoped_ptr<TMemoryStream> ms(new TMemoryStream);
{
boost::scoped_ptr<TStringList> sl(new TStringList);
sl->Text = HTML;
sl->SaveToStream(ms.get(), TEncoding::Unicode);
ms->Position = 0;
}
DelphiInterface<IPersistStreamInit> diPSI;
if (SUCCEEDED(diDoc->QueryInterface(IID_IPersistStreamInit, (void**)&diPSI)) && diPSI)
{
TStreamAdapter* sa = new TStreamAdapter(ms.get(), soReference);
diPSI->Load(*sa);
delete sa; // <-- invalid pointer operation here???
// UPDATED (solution) - instead of the above!!!
// DelphiInterface<IStream> sa(*(new TStreamAdapter(ms.get(), soReference)));
// diPSI->Load(sa);
// DelphiInterface is automatically freed on function end
return S_OK;
}
}
return E_FAIL;
}
Update: I found the solution here - http://www.cyberforum.ru/cpp-builder/thread743255.html
The solution is to use
_di_IStream sa(*(new TStreamAdapter(ms.get(), soReference)));
or...
DelphiInterface<IStream> sa(*(new TStreamAdapter(ms.get(), soReference)));
As it will automatically free the IStream once it is out of scope. At least it should - is there a possible memory leak here? (CodeGuard did not detect any memory leaks).
TStreamAdapter is a TInterfacedObject descendant, which implements reference counting semantics. You are not supposed to delete it at all, you need to let reference counting free the object when it is no longer being referenced by anyone.
Using _di_IStream (which is just an alias for DelphiInterface<IStream>) is the correct way to automate that with a smart pointer. TComInterface<IStream> and CComPtr<IStream> would also work, too.

kotlin inverse boolean safe casting

Let's say I have an object Response. Now I would like to check a boolean variable, success, under Response and do an early return is response is not successful.
if(response == null || !response.success){
return;
} //Java version
Now I would like to use Kotlin's null safety check like following
if(response?.success ?: true){
return
}
If I'm not wrong, if either response or success is null we'll return true inside the if condition. However, if response.success is not null and equals to true, we will still return from the function, which is not what I want . How do I correct this condition ?
I think you have to do
if(!(response?.success ?: false)){
return // null or failed
}
which is equivalent to your java version.
but note: if the null check version is easier to read. You can use that in Kotlin too
you can also flip the condition
response?.success?.let {
// do something when success
}
see the Elvis operator doc for more info
Quite old question, but I just stumbled over it.
The following may be the shortest if clause:
if (response?.success != true) {
//There is either no response, or it was not successful
}

Code analysis warning: CA1062 is really false positive?

In my code, I have a reference variable LogValidacionPagosDTO
public void InsertarArchivoXmlOk(ArchivoXmlDRO archivo, ref LogValidacionPagosDTO archivoRespuesta)
{
//Some code
}
When executing "code analysis" generates this warning
Warning CA1062
In externally visible method 'ArchivoXMLOperacion.ValidacionDuplicadosArchivoXmlFosyga(List<RegistroXmlFosygaDRO>, ref LogValidacionPagosDTO)',
validate local variable ''(*archivoRespuesta)'', which was reassigned from parameter 'archivoRespuesta', before using it.
Then try to validate the object as null
public void InsertarArchivoXmlOk(ArchivoXmlDRO archivo, ref LogValidacionPagosDTO archivoRespuesta)
{
if (archivoRespuesta == null || archivoRespuesta.DetalleRegistros == null)
throw new ExcepcionOperacion(HelperMensaje.Obtener(HelperCodigoMensaje.GEN_0003),
(int)CodigosHTTP.Error, archivoRespuesta, null);
//Some code
}
But this didn't solve the warning. I found this possible solution in Microsoft forum https://social.msdn.microsoft.com/Forums/en-US/fdb00899-c7ea-4e8e-b5f6-9768c2ac0001/ca1062-false-positive-in-externally-visible-method-xxx-validate-local-variable-x-which-was?forum=vstscode
But, I really need to know if this is a false positive, thks!

Managed C++, Object reference not set to an instance of an object

I've run into this problem before, but never in a situation like this. I'm completely confused. As the question states, I'm getting the runtime error "Object reference not set to an instance of an object." Using the debugger tools, I think I've pinpointed the problem to this line:
dataFileLocation = path;
The entire function is here:
void DATReader::SetPath(String^ path)
{
if(!File::Exists(path))
{
MessageBox::Show( "DATReader (missing dat file: \n"+path+"\n )", "Error", MessageBoxButtons::OK, MessageBoxIcon::Exclamation);
return;
}
dataFileLocation = path;
}
dataFileLocation is declared here, but nothing is assigned to it:
ref class DATReader
{
private:
System::String^ dataFileLocation;
// ...
}
Now I know the reason I'm getting the error is because dataFileLocation is assigned to nothing. But I'm having problems assigning it. When I add = 0; to it, it won't build because its a ref class. When I try to assigned it to = 0; in the constructor, it yells at me for trying to convert it from a System::String^ to an int. If I assign it to a = gcnew String(""); it builds, but throws the same runtime exception.
I don't get it, am I reading the debugger wrong, and this isn't the source of the problem at all? I've just started to use managed code recently, so I'm confused :\
You may want to check and make sure your DATReader object isn't null as well It may be throwing the exception at your DATReader.SetPath() call.
This is a nicety in C# that's missing in C++/CLI. C# generates code that ensures this can never be null. Easily seen in the debugger by setting a breakpoint on the method and inspecting "this". Here's an example program that reproduces the exception:
#include "stdafx.h"
using namespace System;
ref class Example {
String^ dataFileLocation;
public:
void SetPath(String^ path) {
dataFileLocation = path; // Set breakpoint here and inspect "this"
}
};
int main(array<System::String ^> ^args)
{
Example^ obj /* = gcnew Example */;
obj->SetPath("foo");
return 0;
}
Remove the /* */ comments to fix. Fix your code by looking at the call stack to find the method that forgot to instantiate the object.
Managed C++ uses nullptr for null references. So you can check:
if (path == nullptr) { ... }
or use:
if (!String::IsNullOrEmpty(path))