What is the use of CComPtr over CComQIPtr in COM? - visual-c++

Can any one explain, What is the use of CComPtr over CComQIPtr in COM?
CComPtr<ISampleInterface> Sample1;
CComQIPtr<ISampleInterface> Sample2;

CComQIPtr is for cases when you want to call QueryInterface() in a convenient manner to know whether an interface is supported:
IInterface1* from = ...
CComQIPtr<IInterface2> to( from );
if( to != 0 ) {
//supported - use
}
This way you can request an interface from a pointer to any (unrelated) COM interface and check whether that request succeeded.
CComPtr is used for managing objects that surely support some interface. You use it as a usual smart pointer with reference counting. It is like CComQIPtr, but doesn't allow the usecase described above and this gives you better type safety.
This code:
IUnknown* unknown = ... ;
CComQIPtr<IDispatch> dispatch( unknown );
compiles and maybe yields a null pointer if unknown is bound to an object that doesn't implement IDispatch. You now have to check for that in runtime which is good if you wanted a runtime check in the first place but bad if you'd prefer a compile time type check.
This code:
IUnknown* unknown = ... ;
CComPtr<IDispatch> dispatch( unknown );
will simply not compile - it yields
error C2664: 'ATL::CComPtr::CComPtr(IDispatch *) throw()' : cannot convert parameter 1 from 'IUnknown *' to 'IDispatch *'
which provides for better compile time type safety.

template<class T,
const IID* piid = &__uuidof(T)>
class CComQIPtr: public CComPtr<T>
Former deduces the UUID of given type automatically, via default template argument.

The following MSDN article explains the difference and recommends using CComPtr instead of CComQIPtr
How to: Create and Use CComPtr and CComQIPtr Instances

Remark on the answer of sharptooth. Just tried to compile sth. like
CComQIPtr<IInterface2> to( from );
and failed. Assignment instead worked:
CComQIPtr<IInterface2> to = from;
Unfortunately I have no time to analyse this further...

"ATL uses CComQIPtr and CComPtr to manage COM interface pointers. Both classes perform automatic reference counting through calls to AddRef and Release. Overloaded operators handle pointer operations. CComQIPtr additionally supports automatic querying of interfaces though QueryInterface."
And where do you use one over the other?
When you do not want to call 'QueryInterface()' 'manually', use 'CComQIPtr':
CComQIPtr( T* lp );
CComQIPtr( const CComQIPtr< T, piid >& lp );
If you pass a pointer type derived from T, the constructor sets p to the T* parameter and calls AddRef. If you pass a pointer type not derived from T, the constructor calls QueryInterface to set p to an interface pointer corresponding to piid.

Related

Code analysis C26408 — Replacing the m_pszHelpFilePath variable in InitInstance

In my application's InitInstance function, I have the following code to rewrite the location of the CHM Help Documentation:
CString strHelp = GetProgramPath();
strHelp += _T("MeetSchedAssist.CHM");
free((void*)m_pszHelpFilePath);
m_pszHelpFilePath = _tcsdup(strHelp);
It is all functional but it gives me a code analysis warning:
C26408 Avoid malloc() and free(), prefer the nothrow version of new with delete (r.10).
When you look at the official documentation for m_pszHelpFilePath it does state:
If you assign a value to m_pszHelpFilePath, it must be dynamically allocated on the heap. The CWinApp destructor calls free( ) with this pointer. You many want to use the _tcsdup( ) run-time library function to do the allocating. Also, free the memory associated with the current pointer before assigning a new value.
Is it possible to rewrite this code to avoid the code analysis warning, or must I add a __pragma?
You could (should?) use a smart pointer to wrap your reallocated m_pszHelpFilePath buffer. However, although this is not trivial, it can be accomplished without too much trouble.
First, declare an appropriate std::unique_ptr member in your derived application class:
class MyApp : public CWinApp // Presumably
{
// Add this member...
public:
std::unique_ptr<TCHAR[]> spHelpPath;
// ...
};
Then, you will need to modify the code that constructs and assigns the help path as follows (I've changed your C-style cast to an arguably better C++ cast):
// First three (almost) lines as before ...
CString strHelp = GetProgramPath();
strHelp += _T("MeetSchedAssist.CHM");
free(const_cast<TCHAR *>(m_pszHelpFilePath));
// Next, allocate the shared pointer data and copy the string...
size_t strSize = static_cast<size_t>(strHelp.GetLength() + 1);
spHelpPath std::make_unique<TCHAR[]>(strSize);
_tcscpy_s(spHelpPath.get(), strHelp.GetString()); // Use the "_s" 'safe' version!
// Now, we can use the embedded raw pointer for m_pszHelpFilePath ...
m_pszHelpFilePath = spHelpPath.get();
So far, so good. The data allocated in the smart pointer will be automatically freed when your application object is destroyed, and the code analysis warnings should disappear. However, there is one last modification we need to make, to prevent the MFC framework from attempting to free our assigned m_pszHelpFilePath pointer. This can be done by setting that to nullptr in the MyApp class override of ExitInstance:
int MyApp::ExitInstance()
{
// <your other exit-time code>
m_pszHelpFilePath = nullptr;
return CWinApp::ExitInstance(); // Call base class
}
However, this may seem like much ado about nothing and, as others have said, you may be justified in simply supressing the warning.
Technically, you can take advantage of the fact that new / delete map to usual malloc/free by default in Visual C++, and just go ahead and replace. The portability won't suffer much as MFC is not portable anyway. Sure you can use unique_ptr<TCHAR[]> instead of direct new / delete, like this:
CString strHelp = GetProgramPath();
strHelp += _T("MeetSchedAssist.CHM");
std::unique_ptr<TCHAR[]> str_old(m_pszHelpFilePath);
auto str_new = std::make_unique<TCHAR[]>(strHelp.GetLength() + 1);
_tcscpy_s(str_new.get(), strHelp.GetLength() + 1, strHelp.GetString());
m_pszHelpFilePath = str_new.release();
str_old.reset();
For robustness for replaced new operator, and for least surprise principle, you should keep free / strdup.
If you replace multiple of those CWinApp strings, suggest writing a function for them, so that there's a single place with free / strdup with suppressed warnings.

finer-grained control than with LD_PRELOAD?

I have a dynamically linked ELF executable on Linux, and I want to swap a function in a library it is linked against. With LD_PRELOAD I can, of course, supply a small library with a replacement for the function that I compile myself. However, what if in the replacement I want to call the original library function? For example, the function may be srand(), and I want to hijack it with my own seed choice but otherwise let srand() do whatever it normally does.
If I were linking to make said executable, I would use the wrap option of the linker but here I only have the compiled binary.
One trivial solution I see is to cut and paste the source code for the original library function into the replacement - but I want to handle the more general case when the source is unavailable. Or, I could hex edit the needed extra code into the binary but that is specific to the binary and also time consuming. Is something more elegant possible than either of these? Such as some magic with the loader?
(Apologies if I were not using the terminology precisely...)
Here's an example of wrapping malloc:
// LD_PRELOAD will cause the process to call this instead of malloc(3)
// report malloc(size) calls
void *malloc(size_t size)
{
// on first call, get a function pointer for malloc(3)
static void *(*real_malloc)(size_t) = NULL;
static int malloc_signal = 0;
if(!real_malloc)
{
// real_malloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc");
*(void **) (&real_malloc) = dlsym(RTLD_NEXT, "malloc");
}
assert(real_malloc);
if (malloc_signal == 0)
{
char *string = getenv("MW_MALLOC_SIGNAL");
if (string != NULL)
{
malloc_signal = 1;
}
}
// call malloc(3)
void *retval = real_malloc(size);
fprintf(stderr, "MW! %f malloc size %zu, address %p\n", get_seconds(), size, retval);
if (malloc_signal == 1)
{
send_signal(SIGUSR1);
}
return retval;
}
The canonical answer is to use dlsym(RTLD_NEXT, ...).
From the man page:
RTLD_NEXT
Find the next occurrence of the desired symbol in the search
order after the current object. This allows one to provide a
wrapper around a function in another shared object, so that,
for example, the definition of a function in a preloaded
shared object (see LD_PRELOAD in ld.so(8)) can find and invoke
the "real" function provided in another shared object (or for
that matter, the "next" definition of the function in cases
where there are multiple layers of preloading).
See also this article.
Just for completeness, regarding editing the function name in the binary - I checked and it works but not without potential hiccups. E.g., in the example I mentioned, one can find the offset of "srand" (e.g., via strings -t x exefile | grep srand) and hex edit the string to "sran0". But names of symbols may be overlapping (to save space), so if the code also calls rand(), then there is only one "srand" string in the binary for both. After the change the unresolved references will then be to sran0 and ran0. Not a showstopper, of course, but something to keep in mind. The dlsym() solution is certainly more flexible.

Misaligned pointer use with std::shared_ptr<NSDate> dereference

I am working in a legacy codebase with a large amount of Objective-C++ written using manual retain/release. Memory is managed using lots of C++ std::shared_ptr<NSMyCoolObjectiveCPointer>, with a suitable deleter passed in on construction that calls release on the contained object. This seems to work great; however, when enabling UBSan, it complains about misaligned pointers, usually when dereferencing the shared_ptrs to do some work.
I've searched for clues and/or solutions, but it's difficult to find technical discussion of the ins and outs of Objective-C object pointers, and even more difficult to find any discussion about Objective-C++, so here I am.
Here is a full Objective-C++ program that demonstrates my problem. When I run this on my Macbook with UBSan, I get a misaligned pointer issue in shared_ptr::operator*:
#import <Foundation/Foundation.h>
#import <memory>
class DateImpl {
public:
DateImpl(NSDate* date) : _date{[date retain], [](NSDate* date) { [date release]; }} {}
NSString* description() const { return [&*_date description]; }
private:
std::shared_ptr<NSDate> _date;
};
int main(int argc, const char * argv[]) {
#autoreleasepool {
DateImpl date{[NSDate distantPast]};
NSLog(#"%#", date.description());
return 0;
}
}
I get this in the call to DateImpl::description:
runtime error: reference binding to misaligned address 0xe2b7fda734fc266f for type 'std::__1::shared_ptr<NSDate>::element_type' (aka 'NSDate'), which requires 8 byte alignment
0xe2b7fda734fc266f: note: pointer points here
<memory cannot be printed>
I suspect that there is something awry with the usage of &* to "cast" the shared_ptr<NSDate> to an NSDate*. I think I could probably work around this issue by using .get() on the shared_ptr instead, but I am genuinely curious about what is going on. Thanks for any feedback or hints!
There were some red herrings here: shared_ptr, manual retain/release, etc. But I ended up discovering that even this very simple code (with ARC enabled) causes the ubsan hit:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSDate& d = *[NSDate distantPast];
NSLog(#"%#", &d);
}
return 0;
}
It seems to simply be an issue with [NSDate distantPast] (and, incidentally, [NSDate distantFuture], but not, for instance, [NSDate date]). I conclude that these must be singleton objects allocated sketchily/misaligned-ly somewhere in the depths of Foundation, and when you dereference them it causes a misaligned pointer read.
(Note it does not happen when the code is simply NSLog(#"%#", &*[NSDate distantPast]). I assume this is because the compiler simply collapses &* on a raw pointer into a no-op. It doesn't for the shared_ptr case in the original question because shared_ptr overloads operator*. Given this, I believe there is no easy way to make this happen in pure Objective-C, since you can't separate the & operation from the * operation, like you can when C++ references are involved [by storing the temporary result of * in an NSDate&].)
You are not supposed to ever use a "bare" NSDate type. Objective-C objects should always be used with a pointer-to-object type (e.g. NSDate *), and you are never supposed to get the "type behind the pointer".
In particular, on 64-bit platforms, Objective-C object pointers can sometimes not be valid pointers, but rather be "tagged pointers" which store the "value" of the object in certain bits of the pointer, rather than as an actual allocated object. You must always let the Objective-C runtime machinery deal with Objective-C object pointers. Dereferencing it as a regular C/C++ pointer can lead to undefined behavior.

is a read or write operation on a pointer value atomic in golang? [duplicate]

Is assigning a pointer atomic in Go?
Do I need to assign a pointer in a lock? Suppose I just want to assign the pointer to nil, and would like other threads to be able to see it. I know in Java we can use volatile for this, but there is no volatile in Go.
The only things which are guaranteed to be atomic in go are the operations in sync.atomic.
So if you want to be certain you'll either need to take a lock, eg sync.Mutex or use one of the atomic primitives. I don't recommend using the atomic primitives though as you'll have to use them everywhere you use the pointer and they are difficult to get right.
Using the mutex is OK go style - you could define a function to return the current pointer with locking very easily, eg something like
import "sync"
var secretPointer *int
var pointerLock sync.Mutex
func CurrentPointer() *int {
pointerLock.Lock()
defer pointerLock.Unlock()
return secretPointer
}
func SetPointer(p *int) {
pointerLock.Lock()
secretPointer = p
pointerLock.Unlock()
}
These functions return a copy of the pointer to their clients which will stay constant even if the master pointer is changed. This may or may not be acceptable depending on how time critical your requirement is. It should be enough to avoid any undefined behaviour - the garbage collector will ensure that the pointers remain valid at all times even if the memory pointed to is no longer used by your program.
An alternative approach would be to only do the pointer access from one go routine and use channels to command that go routine into doing things. That would be considered more idiomatic go, but may not suit your application exactly.
Update
Here is an example showing how to use atomic.SetPointer. It is rather ugly due to the use of unsafe.Pointer. However unsafe.Pointer casts compile to nothing so the runtime cost is small.
import (
"fmt"
"sync/atomic"
"unsafe"
)
type Struct struct {
p unsafe.Pointer // some pointer
}
func main() {
data := 1
info := Struct{p: unsafe.Pointer(&data)}
fmt.Printf("info is %d\n", *(*int)(info.p))
otherData := 2
atomic.StorePointer(&info.p, unsafe.Pointer(&otherData))
fmt.Printf("info is %d\n", *(*int)(info.p))
}
Since the spec doesn't specify you should assume it is not. Even if it is currently atomic it's possible that it could change without ever violating the spec.
In addition to Nick's answer, since Go 1.4 there is atomic.Value type. Its Store(interface) and Load() interface methods take care of the unsafe.Pointer conversion.
Simple example:
package main
import (
"sync/atomic"
)
type stats struct{}
type myType struct {
stats atomic.Value
}
func main() {
var t myType
s := new(stats)
t.stats.Store(s)
s = t.stats.Load().(*stats)
}
Or a more extended example from the documentation on the Go playground.
Since Go 1.19 atomic.Pointer is added into atomic
The sync/atomic package defines new atomic types Bool, Int32, Int64, Uint32, Uint64, Uintptr, and Pointer. These types hide the underlying values so that all accesses are forced to use the atomic APIs. Pointer also avoids the need to convert to unsafe.Pointer at call sites. Int64 and Uint64 are automatically aligned to 64-bit boundaries in structs and allocated data, even on 32-bit systems.
Sample
type ServerConn struct {
Connection net.Conn
ID string
}
func ShowConnection(p *atomic.Pointer[ServerConn]) {
for {
time.Sleep(10 * time.Second)
fmt.Println(p, p.Load())
}
}
func main() {
c := make(chan bool)
p := atomic.Pointer[ServerConn]{}
s := ServerConn{ID: "first_conn"}
p.Store(&s)
go ShowConnection(&p)
go func() {
for {
time.Sleep(13 * time.Second)
newConn := ServerConn{ID: "new_conn"}
p.Swap(&newConn)
}
}()
<-c
}
Please note that atomicity has nothing to do with "I just want to assign the pointer to nil, and would like other threads to be able to see it". The latter property is called visibility.
The answer to the former, as of right now is yes, assigning (loading/storing) a pointer is atomic in Golang, this lies in the updated Go memory model
Otherwise, a read r of a memory location x that is not larger than a machine word must observe some write w such that r does not happen before w and there is no write w' such that w happens before w' and w' happens before r. That is, each read must observe a value written by a preceding or concurrent write.
Regarding visibility, the question does not have enough information to be answered concretely. If you merely want to know if you can dereference the pointer safely, then a plain load/store would be enough. However, the most likely cases are that you want to communicate some information based on the nullness of the pointer. This requires you using sync/atomic, which provides synchronisation capabilities.

Cast a _com_ptr_t to void * and then back to _com_ptr_

How do you cast a COM interface pointer to void pointer and then back to the COM pointer? Here is some code to illustrate my problem. It's very similar to this sample code: _com_ptr_t assignment in VC++
CoInitialize(NULL);
COMLib::ICalcPtr pCalc = COMLib::ICalcPtr("MyLibrary.Calculator");
pCalc->doSomething();
CoUninitialize();
return 0;
Now, if I were to cast the pCalc object to void*, how would I cast it back to COMLib::ICalcPtr? For example, the second line in the following code gives me a compile error 'QueryInterface' : is not a member of 'System::Void'. Obviously, it's trying to call IUknown.QueryInterface() on the object. Preferably I would like to do this without creating a new interface (hence, without implicitly calling QueryInterface and AddRef).
void *test = pCalc;
COMLib::ICalcPtr pCalc2 = test;//'QueryInterface' : is not a member of 'System::Void'
FYI, the reason I'm doing this is that the object is going to be passed around from java to jni VC++ code as a void* type. I'm open to any suggestion on what to do or what is going on behind the scene.
Same way you pass any other opaque structure that either doesn't fit in a pointer or doesn't convert easily: by passing its address.
void* test = new COMLib::ICalcPtr(pCalc);
...
COMLib::ICalcPtr pCalc2 = *(COMLib::ICalcPtr*)test;
delete (COMLib::ICalcPtr*)test;
This will result in calls to AddRef and Release, but not QueryInterface.

Resources