So I am trying to use ImGui, but ImGui::Button("hello") always returns true!
extern "C" __declspec(dllexport) bool Button(const char* text) {
return ImGui::Button(text);
}
What am I doing wrong?
I am using the latest version of ImGui.
(I use this function above for a C# wrapper, which just pinvokes it)
// DirectX Render loop
ImGui.NewFrame();
ImGui.Begin("Test");
if(ImGui.Button("click me")) MessageBox.Show("hello");
ImGui.End();
ImGui.Render();
Related
since yesterday I have been struggling to turn text into label with code from another class, I came to this:
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
TestApp::UI_Error form("test", "test");
Application::Run(% form);
Using the above code, i display a winapi form that receives "test", "test" as 2x const char* on loading, the problem appears when im trying to set the text in labels using these variables
The code looks like this:
public:
UI_Error(const char* errorText, const char* errorCode)
{
InitializeComponent();
this->testLabel->Text = System::Convert::ToString(errorText);
}
For some reason, each time the return value shown in the win forms window is "true", although it should be "test" here, does anyone know the solution?
I tried to use std::string instead of const char*, unfortunately for some reason i get the error code that a static variable is required :(
Maybe I am wrong here, but System::Convert::ToString() seems not to have a method that accepts a const char* pointer. It looks like it gets cast to something else.
Try this instead:
Text = gcnew System::String(errorText);
I'm trying to fire a Social Asynchronous event from a DLL on Windows. There is a tutorial for this here at the bottom.
What I don't understand is the following
When your extension is loaded this callback should fire immediately
and be passed in pointers to the four functions.
I guess I should call the function (RegisterCallbacks) from GML since the callback is defined as dllexport.
Here's the callback function
__declspec (dllexport) void RegisterCallbacks(char *arg1, char *arg2, char *arg3, char *arg4 )
{
void (*CreateAsynEventWithDSMapPtr)(int,int) = (void (*)(int,int))(arg1);
int(*CreateDsMapPtr)(int _num,...) = (int(*)(int _num,...)) (arg2);
CreateAsynEventWithDSMap = CreateAsynEventWithDSMapPtr;
CreateDsMap = CreateDsMapPtr;
bool (*DsMapAddDoublePtr)(int _index,char *_pKey,double value)= (bool(*)(int,char*,double))(arg3);
bool (*DsMapAddStringPtr)(int _index, char *_pKey, char *pVal)= (bool(*)(int,char*,char*))(arg4);
DsMapAddDouble = DsMapAddDoublePtr;
DsMapAddString = DsMapAddStringPtr;
}
But how should I pass a pointer to "CreateAsynEventWithDSMap" from GML? Where do I get those functions?
Old question, but I recently had this problem myself and spent a couple of days scratching my head, so I thought I'd post the answer for the record.
First of all the RegisterCallbacks function in the DLL needs to be __declspec (dllexport) and also extern "C", like any other function exported to GM.
Second, the RegisterCallbacks function should be defined in GM also, not just in the C/C++ file, again just like any other exported function in the extension. The four arguments should be defined as string type. It should look like this: http://i.imgur.com/pppbsWa.png
Now, RegisterCallbacks should fire automatically when you start your game, and the DsMap functions to do async stuff should work. Do not try to call RegisterCallbacks() manually.
I'm an absolute zero at C++. But I need to write a small c++ class for managing a d3ddevice.
My C# code is:
public class HCPPUtils
{
[DllImport("HSpectrum\\Assets\\HCPPUtils.dll")]
private static extern int Getd3Device(ICanvasResourceCreator resourceCreator);}
HCPPUtils hcp = new HCPPUtils();
var pnt = hcp.HGetOrCreate(ResourceCreator);
var d3dDevice = SharpDX.Direct3D11.Device.FromPointer<SharpDX.Direct3D11.Device>(new System.IntPtr(pnt));
My C++ code is:
extern "C"
{
__declspec(dllexport) int Getd3Device
(Microsoft::Graphics::Canvas::ICanvasResourceCreator^ canvasDevice)
{
ComPtr<ID3D11Device> m_device;
__abi_ThrowIfFailed(Windows::Graphics::DirectX::Direct3D11::GetDXGIInterface(canvasDevice->Device,m_device.GetAddressOf()));
return m_device???
}
}
How can i return a IntPtr from C++ code; so, how can i get IntPtr from ComPtr < ID3D11Device >?
[edited]
What I'm doing is...
I have a win2d canvasandimatedcontrol in my c# project. I want to draw direct3d object in it using sharpdx. But I found out that I need to have the d3ddevice object from win2d canvas. And there isn't a c# method to get it.
So the only solution I can imagine is to build a simple c++ project to which I can pass the canvas control and get the d3ddevice. The only problem is how to pass back the d3d device to c#. Sharp DX seems to have just a method Device.FormIntPtr to create it. But I'm not able to pass back the intptr to the c# object.
I tried to implement what Rook wrote, but I cannot understand how it could be useful for my scenario. I mean it could be usueful, but I need to pass the IDirect3DDevice object from a c++ project anyway.
I suspect what you need to do is to read the docs for things like this: http://microsoft.github.io/Win2D/html/M_Microsoft_Graphics_Canvas_CanvasDevice_CreateFromDirect3D11Device.htm
CanvasDevice implements ICanvasResourceCreator, so you could return it directly once you've created it using the static factory method.
Be careful with the scope and lifetime of m_device here, because you don't want its refcount to be decremented when Getd3Device returns and the ComPtr goes out of scope. I'm assuming that it is actually part of a class that will look after its lifetime, but it bears repeating just in case.
I've been trying to access the unity3d device today. This is how I passed the pointer back into unity/managed code:
cpp:
/*
delegate to pass directx device/context back to managed code
see https://forum.unity3d.com/threads/communicating-c-with-c.89930/#post-586885
*/
typedef int(__stdcall *ANSWERCB)(ID3D11Device* ptr);
static ANSWERCB cb;
extern "C" __declspec(dllexport) int GetDevice(ANSWERCB fp)
{
cb = fp;
if (cb)
{
return cb(s_CurrentAPI->GetDevice());
}
return 0;
}
cs:
[DllImport("RenderingPlugin")]
private static extern void GetDevice(Action<IntPtr> callback);
later I call:
GetDevice(devicePtr =>
{
Debug.Log(devicePtr);
if (devicePtr == IntPtr.Zero) return;
device = SharpDX.Direct3D11.Device.FromPointer<SharpDX.Direct3D11.Device>(devicePtr);
...
works fine in the editor as well as the built in the new 2017.1 beta version (as long as you copy the necessary 64bit system dlls to unitys plugin folder)
I'm creating a DLL lib that should be used during runtime (i.e. loaded in Windows 7 with LoadLibrary, closed with FreeLibrary and function handles given by GetProcAddress). This is being done in C++ using Borland C++ Builder. All functions in the DLL should receive some value by reference as parameter (normally std::string).
By now the method I'm using to do this is the following (example) (summarized):
typedef void (*HIS_validity)(string &);
//LoadLibrary
HIS_validity fValidity = (HIS_validity) GetProcAddress(frMain->HIS_DLL.hisLibrary,"checkForValidity");
if (fValidity == NULL) return;
string testeValidade;
fValidity(testeValidade);
const AnsiString testeValidade2(testeValidade.c_str());
if (testeValidade2 != "...")
//etc...
In the DLL:
extern "C" void LIBRARY_API checkForValidity(string &str);
void checkForValidity(string &str)
{
str = "...";
}
Now this code is running fine. The problem is that in some functions I want to pass a whole array of strings by reference. Previously I discovered how to pass a string array by reference here and I though it would be just a matter of ajusting things accordingly:
typedef void (*HIS_patientData)(string (&)[32]);
HIS_patientData fPatientData = (HIS_patientData) GetProcAddress(frMain->HIS_DLL.hisLibrary,"patientDataFields");
string strDado2[32];
fPatientData(strDado2);
frMain->pluginData.patientData.numProntuario = AnsiString(strDado2[cont1++].c_str());
frMain->pluginData.patientData.pacNome = AnsiString(strDado2[cont1++].c_str());
In the DLL:
extern "C" void LIBRARY_API patientDataFields(string (&str)[32]);
void patientDataFields(string (&str)[32])
{
str[0] = "One";
str[1] = "Two";
str[2] = "Three";
//....
}
But here the problem appears. When I compile and run my application, the same problem always come up: if my function in the DLL has only two data attributed to 'str[]', the code goes one after 'fPatientData(strDado2);' but when I read the content of strDado2[0], it has the value of str[1] and strDado2[1] has NULL inside! By the other hand, if I add three or more attributions to 'str[]' in my DLL function, the software always crash when it comes to 'fPatientData(strDado2);' with a pop-up telling "access violation ... in module libstdc++-6.dll".
And I have no ideia what the problem is :T
Thanks for any help,
Momergil
Ok, it seems I found the answer to all such problems... Namely, I'm trying to return a C++ class (std::string) in a "extern "C"" function. It was just a matter of making it return a standart const char* that everything started to run just fine.
Thanks for the contributors,
Momergil
A little background:
I've got a library of C code that is part of larger system (all C). For this particular part of the C library a GUI has to be created which allows users to play around with the options. For the GUI I've chosen QT, since cross-platform support is desired.
I'm using Eclipse and MinGW as IDE and compiler (but I think the question is more language than compiler specific?).
With QT I've created a widget that holds a pointer to a struct implemented in C that contains pointers to several functions that perform the logic of the C library.
//QTWidget.cpp
extern "C" {
#include "c-src/CLogic.h"
//extern char* textHelper;
}
QTWidget::QTWidget(QWidget *parent)
{
//rtw is a struct that contains a function pointer to a member of QTWidget
this->rtw.displayText = &QTWidget::displayText;
this->clogic = CLogic_getInstance(&rtw);
}
//Public SLOT, connected to a button's clicked SIGNAL
void QTWidget::buttonClicked()
{
this->clogic->buttonClicked();
}
void QTWidget::displayText(char *text, int position)
{
//I've tried creating a QString from the char*, but this does not work at all.
//ui.textItem->setText(textHelper);
ui.textItem->setText(text);
}
When the user presses a button in the GUI, the method QTWidget::buttonClicked() is called, which tells the C library to do something. Note the the CLogic struct has a reference to the the QTWidget in the form of a struct RefToWidget which holds a function pointer.
//CLogic.c
static CLogic instance;
void CLogic_buttonClicked()
{
//I've tried several variants here, such as making a global
//char* textHelper = "Hello World";
//that is referenced by using the "extern" keyword in the CPP file above.
instance.rtw->displayText("Hello World", 1);
}
CLogic* CLogic_getInstance(RefToWidget *rtw)
{
instance.rtw = rtw;
instance.buttonClicked = &CLogic_buttonClicked();
}
When debugging this program, I find that all the function calls are executed as intended (when I press a button, the QT slot buttonClicked() is called, the CLogic_buttonClicked() is called, which calls the QTWidget::displayText() as planned, but in this last call the parameters are invalid. The char* text points to 0x1 and claims to be pointing to memory out of bounds, while the int position looks like some random number (uninitialized).
How do I pass this data from C to CPP?
EDIT #Luccas Matteis:
#ifdef __cplusplus
#include "QTWidget.h"
extern "C" {
#endif
struct RefToWidget{
#ifdef __cplusplus
void (QTWidget::*displayLine)(char* text, int lineNumber);
#else
void (*displayLine)(char* text, int lineNumber);
#endif
};
typedef struct RefToWidget RefToWidget;
#ifdef __cplusplus
}
#endif
As said above the function calls behave as expected, but the data is not passed "correctly" (even though that when I look at it, the code seems a bit... weird... ;))
Your problem is not passing the char * from C to C++ but calling a C++ function from C. I presume that CLogic.c is compiled as a C library? If not, can you rename it to CLogic.cpp or use a compiler switch to force it to be compiled as C++ even though it has a C file extension?
If you want a C++ GUI on a C library/system, you need to use proper Model-View-Controller logic. Here the C++ code is the View and the Controller while the C code is the Model (as best as I can tell from your description). You need to make it so you set and get data from the model but the model never calls the View or Controller as you are trying to do.
Think about what you are REALLY trying to do. If you just want to display a static string when the button is pressed, why go to the bother of calling into CLogic.c? If you want to display a string that depends upon the state of the CLogic instance then instead do something like:
void QTWidget::buttonClicked()
{
char *display_text = this->clogic->get_button_click_text();
ui.textItem->setText(display_text);
}
I guess the problem is that the structure holds a pointer to a member function. The member function probably expects the first parameter to be 'this' - the object it refers to. So, in fact what you are seeing in debug as text is the second parameter.
A 'solution' would probably be to do something like "instance.rtw->displayText(instance.rtw, "Hello World", 1)", but have no idea if it is portable etc.
Edit: Saying it explicitly: the 'solution' stated above is just to try and check if this is the problem. As the comments are saying this is a horrible hack that might not work even on the same compiler.
I don't think that you should call a C++ method from C. Normally you need to go through a static method that dereferences a pointer argument