How do I get the device hardware type in Unified API? Here's an example of how to do it in Classic API.. In that example, the "[DllImport(Constants.SystemLibrary)]" part doesn't compile. It seems that has changed in Unified API?
So this is the old Classic code. How do I do this in Unified after including "ObjCRuntime"?
[DllImport(MonoTouch.Constants.SystemLibrary)]
static internal extern int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string property, IntPtr output, IntPtr oldLen, IntPtr newp, uint newlen);
public DeviceHardware ()
{
var pStr = Marshal.AllocHGlobal(length);
sysctlbyname(HardwareProperty, pStr, pLen, IntPtr.Zero, 0);
string DeviceTypeString = Marshal.PtrToStringAnsi(pStr);
}
Solution below. I had to use "ObjCRuntime" instead of "MonoTouch"
[DllImport(ObjCRuntime.Constants.SystemLibrary)]
The Constants class is in the ObjCRuntime namespace, so you just need to add this using clause at the top of the file:
using ObjCRuntime;
Related
Is there a reference to a class property in C++Builder, analogous to a regular reference in C++? To understand what I mean, I will give the code (so far this is my solution to the problem):
void change(TControl* object) {
struct TAccessor : TControl { __property Text; };
static_cast<TAccessor*>(object)->Text = L"some text";
}
This function allows you to change the Text property of any object inherited from TControl.
But maybe there is a more elegant solution to this problem?
Your approach will update the Text of any TControl, even if it doesn't actually expose access to Text (which is declared protected in TControl itself, derived classes decide whether to promote it to public/__published as needed).
To account for that fact, you would have to use RTTI to discover if Text is accessible or not. You can also use RTTI to set the property value, without resorting to the Accessor trick.
For example, old-style RTTI (via the <TypInfo.hpp> header) works only with __published properties, nothing else, eg:
#include <TypInfo.hpp>
void change(TControl* object) {
if (IsPublishedProp(object, _D("Text"))
SetStrProp(object, _D("Text"), _D("some text"));
}
Alternatively:
#include <TypInfo.hpp>
void change(TControl* object) {
PPropInfo prop = GetPropInfo(object, _D("Text"), TTypeKinds() << tkUString);
if (prop)
SetStrProp(object, prop, _D("some text"));
}
Whereas newer-style Extended RTTI (via the <Rtti.hpp> header) supports fields, methods, and properties, and all the supported member visibilities, eg:
#include <Rtti.hpp>
typedef Set<TMemberVisibility, mvPrivate, mvPublished> TMemberVisibilitySet;
void change(TControl* object) {
static const TMemberVisibilitySet WantedVisibilities = TMemberVisibilitySet() << mvPublic << mvPublished;
TRttiContext ctx;
TRttiType *type = ctx.GetType(object->ClassType());
TRttiProperty* prop = type->GetProperty(_D("Text"));
if ((prop) && (WantedVisibilities.Contains(prop->Visibility)) && (prop->IsWritable))
prop->SetValue(object, _D("some text"));
}
I am still using deprecated TServerSocket component.
I would like to bind TServerSocket to a specific IP. This question has been previously asked before for Delphi in this site: How to Bind a TServerSocket to a specific IP address
However I couldn't make it work in C++ Builder.
My code is:
class ServerWrapper : private TServerSocket {
public:
ServerWrapper();
private:
};
ServerWrapper::ServerWrapper()
: TServerSocket (0)
{
//---
}
ServerWrapper* pServer =0;
//...
//..
//.
// And in a function:
pServer = new ServerWrapper;
pServer->Address = "192.168.0.1" ;
pServer->Active = true;
However it doesn't compile.
It says:
E2247 'TAbstractSocket::Address' is not accessible
I am using C++ Builder 10.1.2 Berlin by the way.
It doesn't work because you did not translate the Delphi code to C++ correctly.
For one thing, you are using private inheritance instead of public inheritance. So all public and protected members inherited from TServerSocket will be private in ServerWrapper. Delphi has no notion of protected/private inheritance, only public inheritance.
But more importantly, Delphi has a notion of implicit friendship. Within a unit, all classes have full access to private/protected members of other classes that are declared in the same unit. That includes inherited protected members. The Delphi example in the other question takes advantage of that feature, by declaring a local helper class to implicitly gain public access to the Address property for the unit that declares the helper.
But C++ has no notion of implicit friendship. To translate the Delphi example to C++, you have to explicitly promote access to the protected Address property.
A literal translation of the Delphi code would look like this in C++:
class TServerSocketAccess : public TServerSocket
{
public:
__property Address;
// or:
// using TServerSocket::Address;
};
((TServerSocketAccess*)ServerSocket1)->Address = "192.168.0.1";
ServerSocket1->Active = true;
Applied to your ServerWrapper class, it would look like this:
class ServerWrapper : public TServerSocket
{
public:
ServerWrapper();
__property Address;
// or:
// using TServerSocket::Address;
};
ServerWrapper::ServerWrapper()
: TServerSocket (0)
{
//---
}
ServerWrapper* pServer = 0;
//...
pServer = new ServerWrapper;
pServer->Address = "192.168.0.1";
pServer->Active = true;
I'm working on an audio debug feature and trying to get the AudioUnit.AudioUnitPropertyIDType.Latency property value of my audio unit using Xamarin.iOS. Unfortunately I don't see related method to retrieve the value property value like audioUnit.GetParameter.
Though I can see and successfully set properties using audioUnit.SetParameter method.
Did I miss something?
Not an answer but AudioUnit has private AudioUnitSetProperty method which is exposed as SetAudioFormat, SetCurrentDevice and a number of other methods, but not for Latency. Looks like it wasn't implemented by Xamarin. But you always can use reflection ;)
public void SetAudioFormat(AudioStreamBasicDescription audioFormat, AudioUnitScopeType scope, uint audioUnitElement = 0U)
{
int k = AudioUnit.AudioUnitSetProperty(this.handle, AudioUnitPropertyIDType.StreamFormat, scope, audioUnitElement, ref audioFormat, (uint) Marshal.SizeOf<AudioStreamBasicDescription>(audioFormat));
if (k != 0)
throw new AudioUnitException(k);
}
I want to expose my MXBeans on Apache-Tomcat 7.0.
Though my MXBean registers successfully, I am unable to add description to the Operations that are exposed by thoese MXBeans.
Registering MXBeans
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName m_mxbeanOName = new ObjectName( "MyMXBean:type=" + "MyComponent"+",name=MyMXBean");
MyMXBean m_mxbean = new MyMXBean ();
if(!mbs.isRegistered(m_mxbeanOName))
mbs.registerMBean(m_mxbean, m_mxbeanOName);
MyMXBean Interface
public interface MyMXBean {
public int add (int x, int y);
}
MyMXBean Implementation
import com.sun.org.glassfish.gmbal.Description;
import com.sun.org.glassfish.gmbal.DescriptorFields;
import com.sun.org.glassfish.gmbal.Impact;
import com.sun.org.glassfish.gmbal.ManagedOperation;
public class MyMXBeanImpl implements MyMXBean {
#ManagedOperation(impact=Impact.ACTION_INFO)
#Description("Integer Addition: First parameter is the augend and second parameter is the addend.")
#DescriptorFields({"p1=augend","p2=addend"})
public int add(int x, int y) {
return x + y;
}
The annotation #ManagedOperation, #Description, #DescriptorFields has no effect on the jconsole. JConsole continues to show default values
Please tell me ways to show the description about my MXBean operations on JConsole.
The cleanest way I have found to do this is to use StandardMBean (or StandardEmitterMBean) as the actual object you register with JMX. Then, subclass StandardMBean and override the various getDescription methods. In those methods, read your annotations that contain the descriptions.
I found this very nice blogentry with code for #Descriptor and #Name attributes and a AnnotatedStandardMXBean wrapper which handles this.
http://actimem.com/java/jmx-annotations/
Sample MXBean using this:
#MXBean
#Description("A test resource")
public interface SampleMXBean {
#Description("string#1")
String getString1();
#Description("string#2")
String getString2();
#Description("string#3")
String string3(#Description("int i") #Name("i") int i, #Description("long j") #Name("j") long j);
}
I'm trying to use C++ Template 'mixins' to create some new VCL components with shared additional functionality. Example...
template <class T> class Mixin : public T
{
private:
typedef T inherited;
// ...additional methods
public:
Mixin(TComponent *owner) : inherited(owner)
{
// .. do stuff here
};
};
Used like this:
class MyLabel : public Mixin<TLabel>
{
....
}
class MyEdit : public Mixin<TEdit>
{
....
}
Now, everything compiles fine, and the mixin stuff seems to work - until I try and save the component to a stream using TStream->WriteComponent, where the inherited properties (eg TLabel.Width/Height/etc.) don't get written. This is even with a 'null' mixin like the one shown above.
My code works fine when just deriving classes directly from TForm, TEdit, etc - and the class is correctly registered with the streaming system.
The quick/simple answer is: no; when dealing with a template, the compiler won't generate the proper descriptors to make streaming working. However, since this has come up before, I peeked under the cover to find out what's missing. And what I found is that it's almost there. So here's a little more information.
Upfront the compiler will never treat a template-based type as a Delphi. For example, do something like this:
void testing()
{
__classid(Mixin<Stdctrls::TLabel>); // Error Here
}
... and you'll see the error
"Error E2242 test.cpp 53: __classid requires Delphi style class type (i.e. class marked __declspec(delphiclass) or derived from System::TObject) in function testing()"
This basically says the compiler does not consider this type/class as compatible with Delphi-classes [i.e. those that derive from TObject]. Internally there's just a flag on the symbol that says whether the type is delphi-compatible or not. And I noticed that I could trick the compiler into marking the type as delphi-style if I forced it to walk up the hierarchy.. which is something it has to do if I create an instance of the object. So, with this hack the error goes away:
void testing()
{
typedef Mixin<Stdctrls::TLabel> __ttype;
std::auto_ptr<__ttype> c2(new __ttype(0));
__classid(Mixin<Stdctrls::TLabel>); // No more errors here
}
But much nicer was actually to use the __declspec(delphiclass) directly on the template, as in:
template <class T>
class __declspec(delphiclass) Mixin : public T {
private:
int i;
typedef T inherited;
public:
__fastcall Mixin(TComponent *owner) : inherited(owner) {};
};
So now that the compiler treats the type as a delphi-style class without hacks, I peeked a little more and found the issue you're probably running into: Delphi classes have the TTypeData.PropCount field - http://docwiki.embarcadero.com/VCL/en/TypInfo.TTypeData - which is a sum of the class' properties, including those of its base classes. Due to the way the various pieces of information are computed, the compiler writes out a '0' for that field when a template is involved:(
You can see this by printing out the PropCount, as in:
#include <Stdctrls.hpp>
#include <cstdio>
#include <memory>
#include <utilcls.h>
class TCppComp : public Classes::TComponent {
int i;
public:
__fastcall TCppComp(TComponent* owner): Classes::TComponent(owner) {};
__published:
__property int AAAA = {read=i, write=i};
};
template <class T>
class __declspec(delphiclass) Mixin : public T {
private:
int i;
typedef T inherited;
public:
__fastcall Mixin(TComponent *owner) : inherited(owner) {};
};
typedef Mixin<TCppComp> TMixinComp;
void showProps(TClass meta) {
PTypeInfo pInfo = PTypeInfo(meta->ClassInfo());
int Count = GetPropList(pInfo, tkAny, NULL);
TAPtr<PPropInfo> List(new PPropInfo[Count]);
std::printf("Class: %s - Total Props:%d\n",
AnsiString(pInfo->Name).c_str(), Count);
GetPropList(pInfo, tkAny, *(reinterpret_cast<PPropList*>(&List)));
for (int i = 0; i < Count; i++) {
AnsiString propName(List[i]->Name);
std::printf("\t%s\n", propName.c_str());
}
}
void test() {
showProps(__classid(TCppComp));
showProps(__classid(TMixinComp));
}
int main() {
test();
return 0;
}
When run the above prints:
Class: TCppComp - Total Props:3
AAAA
Name
Tag
Class: #%Mixin$8TCppComp% - Total Props:0
IOW, Mixin shows up with '0' published properties while its base type has 3:(
I suspect the streaming system relies on this count and that's why inherited properties are not being written out in your setup.
I considered tweaking the generated descriptors at runtime but since we write them to _TEXT it's bound to trigger DEP.
I'll look at the logic that computes the PropCount to see if there's some way to get it to compute the correct number. If time allows, please do open a QC for this: now that I've peek underneath, I believe it would not require much effort to get this working as expected.
Cheers,
Bruneau
PS: In my sample I even had the Mixin publish a property and the compiler generated the correct descriptor for that property; however, the total count was still zero.