I have a class named NativeMethods.cs which contains all extern methods:
internal static class NativeMethods
{
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool wow64Process);
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
internal static extern int RegOpenKeyEx(
IntPtr hKey,
string subKey,
int ulOptions,
int samDesired,
out int hkResult);
}
The assembly containing this class has a corresponding .Moles file. All other classes included in the assembly can be moled and stubbed properly, except this one.
There is no MNativeMethods that we can use for detouring. Is there a special case against the class name "NativeMethods" (Highly unlikely)? Or a special case against extern methods?
Moles is capable of detouring calls to managed code. This class is clearly not dealing with managed code. Try creating a stub for this class, manually. This means crating an INativeMethods interface, have NativeMethods implement INativeMethods, and then use the interface as the stub, as usual. Moles will then generate stub type SINativeMethods from the interface, for use in test projects.
"Thus, if a method has no body (such as an abstract method), we cannot detour it." - Moles Dev
Related
What I done:
validator.h:
class UTILSSHARED_EXPORT Validator: public QObject {
Q_OBJECT
public:
Validator(QObject *parent = 0);
~Validator();
Q_INVOKABLE static bool validateMobile(const QString target);
};
main.cpp:
qmlRegisterUncreatableType<Validator>("CT.Utils", 1, 0, "ValidatorKit", "It just a kit");
qml:
import CT.Utils 1.0
ValidatorKit.validateMobile("112344")
But unfortunately, I got an error that said: TypeError: Property 'validateMobile' of object [object Object] is not a function
So, how can I expose static method to qml correctly?
Could anybody help me? Thanks a lot.
qmlRegisterUncreatableType() is about something else entirely.
What you actually need to do is expose a Validator instance as a context property to QML, or even better, implement the validator as a singleton.
qmlRegisterSingletonType<Validator>("CT.Utils", 1, 0, "ValidatorKit", fooThatReturnsValidatorPtr);
Addition to singleton type, it is possible to create a private singleton attached properties object which contains only static functions. It is more clear with an example:
class StaticValidator;
class Validator : public QObject {
Q_OBJECT
public:
Validator(QObject *parent = 0);
~Validator();
// Put implementation in a source file to prevent compile errors.
static StaticValidator* qmlAttachedProperties(QObject *object) {
Q_UNUSED(object);
static StaticValidator instance;
return &instance;
}
static bool validateMobile(const QString& target);
};
//Q_OBJECT does not work in inner classes.
class StaticValidator : public QObject {
Q_OBJECT
public:
Q_INVOKABLE inline bool validateMobile(const QString& target) const {
return Validator::validateMobile(target);
}
private:
StaticValidator(QObject* parent = nullptr) : QObject(parent) {}
friend class Validator;
};
QML_DECLARE_TYPE(Validator)
QML_DECLARE_TYPEINFO(Validator, QML_HAS_ATTACHED_PROPERTIES)
Register type in main or somewhere:
qmlRegisterType<Validator>("Validator", 1, 0, "Validator");
Call function in QML:
import Validator 1.0
...
var result = Validator.validateMobile(target);
It should also work in Qt4, but I didn't test it.
In my Binding library i have the following Method:
public static unsafe int ExportConfig (int p0)
I need to turn it to:
public static unsafe int ExportConfig (ref int p0)
I am trying to do that with Metadata.xml, but all i do make the compiler delete the method, anyway i can do that?
I've got an interface with a simple signature:
namespace Serial {
public interface struct ISerial
{
uint16_t func1();
uint16_t func2();
};
}
and then a class type which implements the interface
namespace Serial {
public delegate void MyEventClass();
public ref class MySerial sealed : public ISerial {
public:
event MyEventClass MyEvent;
MySerial();
...
};
}
but elsewhere, as a default parameter to a function, I try to store a reference to a type MySerial as an ISerial ^
void
begin(
Serial::ISerial ^s = ref new Serial::MySerial
);
causes: error C1001: An internal error has occurred in the compiler.
when I remove the event from the class definition, everything compiles fine. I'm finding little information on this error.
I verified this on VS 2013 and it works with a few minor changes (all generated based on normal compiler errors, not an ICE). I don't have VS 2015 available right now, but will log a bug if it still repros.
First the struct (should be unchanged)
namespace Serial
{
public interface struct ISerial
{
uint16_t func1();
uint16_t func2();
};
}
Then the class (couple of changes noted below):
namespace Serial
{
public delegate void MyEventClass();
public ref class MySerial sealed : public ISerial{
public:
event MyEventClass^ MyEvent;
MySerial(){}
virtual uint16_t func1() { return 42; }
virtual uint16_t func2() { return 42; }
};
}
And the usage:
void foo()
{
using namespace Serial;
ISerial^ foo = ref new MySerial();
}
Basically you need to add the hat (^) to the event type, and you need to add virtual to the methods (but do not add override).
See more here on MSDN
I'm been curious about the declaration syntax of Collections::Generic::Dictionary
class in C++/CLI.
Normally we declare a reference in a class and initialize it:
public ref class CDemo {
private: ClassA ^ m_InstanceA;
// Why the absence of '^'.
private: Dictionary<int, int> m_Dic;
CDemo() :
m_InstanceA(gcnew ClassA()),
m_Dic(gcnew Dictionary<int, int>())
{...}
};
Could someone explains please why should the '^' absent there?
What's more, if I were to use the dictionary above as a TValue of another dictionary,
I have to declare it like this:
Dictionary<T, Dictionary<T, T>^ > m_Dic; // A '^' in the TValue parameter, which is
// normal, but same question as above,
// I don't have to declare m_Dic as ^ ?
Thanks.
This is not specific to Dictionary. This syntax is a way to help map C++ semantics onto managed types. In general:
ref class A
{
ReferenceType m_obj;
};
is roughly equivalent to
class A : IDisposable
{
private ReferenceType m_obj;
void Dispose() { m_obj.Dispose(); }
}
in C# if ReferenceType implements IDisposable. It is perfectly possible to write
ref class A
{
ReferenceType^ m_obj;
};
This does not have the implicit IDisposable support. The other difference is that you can return a ReferenceType^ from a method, this is not supported with just plain ReferenceType. For example:
ref class A
{
ReferenceType^ m_obj;
ReferenceType^ GetIt() { return m_obj; }
};
will compile,
ref class A
{
ReferenceType m_obj;
ReferenceType GetIt() { return m_obj; } // won't compile
ReferenceType^ OtherGetIt() { return m_obj; } // neither will this
};
A similar distinction is provided for automatic (stack variables)
ReferenceType local;
local.Stuff();
is desugared by the compiler to
try {
ReferenceType^ local = gcnew ReferenceType();
local->Stuff();
} finally {
delete local; // invokes Dispose() (~ReferenceType)
}
These features bring the familiar idiom of RAII to C++/CLI with managed types.
EDIT:
Yes, the Dispose method of IDisposable is analogous to a C++ destructor. If ReferenceType doesn't implement IDisposable (doesn't have a dtor), and it is the only member, A will also not implement IDisposable (not have an implicit dtor). In C++/CLI you implement IDisposable by providing a dtor (for managed types).
C#
namespace TestController
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IController {
void DoSomething();
}
[ComVisible(true), ClassInterface(ClassInterfaceType.None)]
public class ControllerImpl : IController {
public void DoSomething()
{
throw new NotImplementedException();
}
}
}
C++
#import "c:\prj\Controller\bin\Debug\TestController.tlb"
using namespace TestController;
int _tmain(int argc, _TCHAR* argv[])
{
IControllerPtr ctrl;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
while (true) {
HRESULT hr = ctrl.CreateInstance(__uuidof(ControllerImpl));
ctrl = 0;
}
return 0;
}
Hi all,
I need to provide access to my .NET class library from unmanaged code. Beeing totally new to the subject, I spent several days studying the COM / interop, then defined and implemented a COM accessible interface, made a test run and everything just worked, until I noticed something that seemed as a memory leak. I isolated the offending statements, but still have no clue why is the above code broken.
This is probably a case of:
http://jpassing.com/2009/03/26/rcw-reference-counting-rules-com-reference-counting-rules/
Specifically, .NET uses RCW reference counting rules, which are different to the usual reference counting rules in COM applications.
This results in apparent leaks until the .NET RCW reference counting observes that a given object is no-longer used, and this requires cooperation from its garbage collector.