
I am having trouble figuring out how to pass callbacks to C. Given the definition below it is not clear how to define a function and pass it. I tried: getNumberOfRows :: CInt getNumberOfRows = 1 table <- wxcGridTableCreate getNumberOfRows… but the compiler barks at me: src/MainGui.hs:577:32: Not in scope: data constructor ‘Ptr’ even through I do the imports: import Foreign import Foreign.C There is also a _obj as the first value of wxcGridTableCreate and the callbacks, and I am not sure how to make a this* for it. I would have throughout that wxcGridTableCreate would return a Ptr. The goal is to pass haskell functions into wxcGridTableCreate so the grid can call back to haskell. Can someone show an example of just this one function, how to wrap a Ptr around it, and what to do with _obj? DEFINITION wxcGridTableCreate :: Ptr a -> Ptr b -> Ptr c -> Ptr d -> Ptr e -> Ptr f -> Ptr g -> Ptr h -> Ptr i -> Ptr j -> Ptr k -> Ptr l -> Ptr m -> Ptr n -> Ptr o -> Ptr p -> Ptr q -> IO (WXCGridTable ()) wxcGridTableCreate _obj _EifGetNumberRows _EifGetNumberCols _EifGetValue _EifSetValue _EifIsEmptyCell _EifClear _EifInsertRows _EifAppendRows _EifDeleteRows _EifInsertCols _EifAppendCols _EifDeleteCols _EifSetRowLabelValue _EifSetColLabelValue _EifGetRowLabelValue _EifGetColLabelValue = withObjectResult $ wx_ELJGridTable_Create _obj _EifGetNumberRows _EifGetNumberCols _EifGetValue _EifSetValue _EifIsEmptyCell _EifClear _EifInsertRows _EifAppendRows _EifDeleteRows _EifInsertCols _EifAppendCols _EifDeleteCols _EifSetRowLabelValue _EifSetColLabelValue _EifGetRowLabelValue _EifGetColLabelValue foreign import ccall "ELJGridTable_Create" wx_ELJGridTable_Create :: Ptr a -> Ptr b -> Ptr c -> Ptr d -> Ptr e -> Ptr f -> Ptr g -> Ptr h -> Ptr i -> Ptr j -> Ptr k -> Ptr l -> Ptr m -> Ptr n -> Ptr o -> Ptr p -> Ptr q -> IO (Ptr (TWXCGridTable ())) typedef int _cdecl (*TGridGetInt)(void* _obj); typedef int _cdecl (*TGridIsEmpty)(void* _obj, int row, int col); typedef void* _cdecl (*TGridGetValue)(void* _obj, int row, int col); typedef void _cdecl (*TGridSetValue)(void* _obj, int row, int col, void* val); typedef void _cdecl (*TGridClear)(void* _obj); typedef int _cdecl (*TGridModify)(void* _obj, int pos, int num); typedef int _cdecl (*TGridMultiModify)(void* _obj, int num); typedef void _cdecl (*TGridSetLabel)(void* _obj, int idx, void* val); typedef void* _cdecl (*TGridGetLabel)(void* _obj, int idx); EWXWEXPORT(void*,ELJGridTable_Create)(void* self,void* _EifGetNumberRows,void* _EifGetNumberCols,void* _EifGetValue,void* _EifSetValue,void* _EifIsEmptyCell,void* _EifClear,void* _EifInsertRows,void* _EifAppendRows,void* _EifDeleteRows,void* _EifInsertCols,void* _EifAppendCols,void* _EifDeleteCols,void* _EifSetRowLabelValue,void* _EifSetColLabelValue,void* _EifGetRowLabelValue,void* _EifGetColLabelValue) { return (void*)new ELJGridTable (self,

Sorry but I am having trouble understanding your post, but here's some information you might find useful: * If you want to pass a callback to a C function, you need to use a FunPtr. In particular, you need to create a "wrapper" foreign import that will allow you to convert a haskell function to a FunPtr that can be then passed to C and called by C. The docs on FunPtr [1] explain how to do this. * Ptr is not a data constructor, its a type constructor, so e.g. `Ptr CInt` is a valid type, but `Ptr 4` is not a valid expression. If you want to store a value in the heap and then create a pointer to it, you can use the `with` function [2]. So e.g. in `with 5 $ \p -> ...`, p is a `Ptr CInt`. Remember that `Ptr`s are to useful for passing callbacks though. [1] https://hackage.haskell.org/package/base-4.8.0.0/docs/Foreign-Ptr.html#t:Fun... [2] https://hackage.haskell.org/package/base-4.8.0.0/docs/Foreign-Marshal-Utils.... Michael Jones, wrote:
I am having trouble figuring out how to pass callbacks to C.
Given the definition below it is not clear how to define a function and pass it. I tried:
getNumberOfRows :: CInt getNumberOfRows = 1
table <- wxcGridTableCreate getNumberOfRows…
but the compiler barks at me:
src/MainGui.hs:577:32: Not in scope: data constructor ‘Ptr’
even through I do the imports:
import Foreign import Foreign.C
There is also a _obj as the first value of wxcGridTableCreate and the callbacks, and I am not sure how to make a this* for it. I would have throughout that wxcGridTableCreate would return a Ptr.
The goal is to pass haskell functions into wxcGridTableCreate so the grid can call back to haskell.
Can someone show an example of just this one function, how to wrap a Ptr around it, and what to do with _obj?
DEFINITION
wxcGridTableCreate :: Ptr a -> Ptr b -> Ptr c -> Ptr d -> Ptr e -> Ptr f -> Ptr g -> Ptr h -> Ptr i -> Ptr j -> Ptr k -> Ptr l -> Ptr m -> Ptr n -> Ptr o -> Ptr p -> Ptr q -> IO (WXCGridTable ()) wxcGridTableCreate _obj _EifGetNumberRows _EifGetNumberCols _EifGetValue _EifSetValue _EifIsEmptyCell _EifClear _EifInsertRows _EifAppendRows _EifDeleteRows _EifInsertCols _EifAppendCols _EifDeleteCols _EifSetRowLabelValue _EifSetColLabelValue _EifGetRowLabelValue _EifGetColLabelValue = withObjectResult $ wx_ELJGridTable_Create _obj _EifGetNumberRows _EifGetNumberCols _EifGetValue _EifSetValue _EifIsEmptyCell _EifClear _EifInsertRows _EifAppendRows _EifDeleteRows _EifInsertCols _EifAppendCols _EifDeleteCols _EifSetRowLabelValue _EifSetColLabelValue _EifGetRowLabelValue _EifGetColLabelValue foreign import ccall "ELJGridTable_Create" wx_ELJGridTable_Create :: Ptr a -> Ptr b -> Ptr c -> Ptr d -> Ptr e -> Ptr f -> Ptr g -> Ptr h -> Ptr i -> Ptr j -> Ptr k -> Ptr l -> Ptr m -> Ptr n -> Ptr o -> Ptr p -> Ptr q -> IO (Ptr (TWXCGridTable ()))
typedef int _cdecl (*TGridGetInt)(void* _obj); typedef int _cdecl (*TGridIsEmpty)(void* _obj, int row, int col); typedef void* _cdecl (*TGridGetValue)(void* _obj, int row, int col); typedef void _cdecl (*TGridSetValue)(void* _obj, int row, int col, void* val); typedef void _cdecl (*TGridClear)(void* _obj); typedef int _cdecl (*TGridModify)(void* _obj, int pos, int num); typedef int _cdecl (*TGridMultiModify)(void* _obj, int num); typedef void _cdecl (*TGridSetLabel)(void* _obj, int idx, void* val); typedef void* _cdecl (*TGridGetLabel)(void* _obj, int idx);
EWXWEXPORT(void*,ELJGridTable_Create)(void* self,void* _EifGetNumberRows,void* _EifGetNumberCols,void* _EifGetValue,void* _EifSetValue,void* _EifIsEmptyCell,void* _EifClear,void* _EifInsertRows,void* _EifAppendRows,void* _EifDeleteRows,void* _EifInsertCols,void* _EifAppendCols,void* _EifDeleteCols,void* _EifSetRowLabelValue,void* _EifSetColLabelValue,void* _EifGetRowLabelValue,void* _EifGetColLabelValue) { return (void*)new ELJGridTable (self,
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Ok, I’ll give some details and since I made it work using your description of Ptr a, I'll describe the solution. And it will leave one question at the end.
There is a class in wxWidgets called wxGridTableBase. It has callbacks and definitions of signatures that are C typed.
C++ CLASS WITH CALLBACKS
extern "C"
{
typedef int _cdecl (*TGridGetInt)(void* _obj);
typedef int _cdecl (*TGridIsEmpty)(void* _obj, int row, int col);
…
}
class ELJGridTable : public wxGridTableBase
{
private:
void* EiffelObject;
TGridGetInt EifGetNumberRows;
TGridGetInt EifGetNumberCols;
...
public:
ELJGridTable (void* _obj,
void* _EifGetNumberRows,
void* _EifGetNumberCols,
… ): wxGridTableBase()
{
EiffelObject = _obj;
EifGetNumberRows = (TGridGetInt)_EifGetNumberRows;
EifGetNumberCols = (TGridGetInt)_EifGetNumberCols;
...
};
int GetNumberRows() {return EifGetNumberRows(EiffelObject);};
int GetNumberCols() {return EifGetNumberCols(EiffelObject);};
...
};
WXHASKELL WRAPPER
wxcGridTableCreate :: Ptr a -> Ptr b -> ... -> IO (WXCGridTable ())
wxcGridTableCreate _obj _EifGetNumberRows _EifGetNumberCols _EifGetValue _...
= withObjectResult $
wx_ELJGridTable_Create _obj _EifGetNumberRows _EifGetNumberCols ...
foreign import ccall "ELJGridTable_Create" wx_ELJGridTable_Create :: Ptr a -> Ptr b -> Ptr c -> ... -> IO (Ptr (TWXCGridTable ()))
The question is how to call wxcGridTableCreate with Haskell functions.
So here are a few callbacks:
CALLBACK FUNCTIONS
getNumberOfRows :: Ptr CInt -> CInt
getNumberOfRows p = 1
foreign import ccall "wrapper"
wrapNumberOfRows :: (Ptr CInt -> CInt) -> IO (FunPtr (Ptr CInt -> CInt))
getNumberOfCols :: Ptr CInt -> CInt
getNumberOfCols p = 1
foreign import ccall "wrapper"
wrapNumberOfCols :: (Ptr CInt -> CInt) -> IO (FunPtr (Ptr CInt -> CInt))
getValue :: Ptr CInt -> CInt -> CInt -> CWString
getValue p r c = do
unsafePerformIO $ newCWString “Str"
foreign import ccall "wrapper"
wrapGetValue :: (Ptr CInt -> CInt -> CInt -> CWString) -> IO (FunPtr (Ptr CInt -> CInt -> CInt -> CWString))
MAKE WRAPPERS
wGetNumberOfRows <- wrapNumberOfRows getNumberOfRows
wGetNumberOfCols <- wrapNumberOfCols getNumberOfCols
wGetValue <- wrapGetValue getValue
CREATE TABLE
table <- wxcGridTableCreate n
(castFunPtrToPtr wGetNumberOfRows)
(castFunPtrToPtr wGetNumberOfCols)
(castFunPtrToPtr wGetValue)
The key to making it work was to make a FunPtr and then use the castFunPtrToPtr. This was the main break through.
Now the question. There is one function with CWString:
getValue :: Ptr CInt -> CInt -> CInt -> CWString
getValue p r c = do
unsafePerformIO $ newCWString “Str”
The problem is newCWString creates a string that must be freed, and wxWidgets does not free it. This results in a memory leak.
In a real application, I’ll probably store a String in a TVar so that some thread can keep it up to date. I could use other TVars to hold the CWString and free it each time a new value is created. But, it would be better if there was some way to guarantee it is freed, even with exceptions, etc. The best would be if when the function returns, it automatically freed the string.
Is there a way express the callback function so that it frees the string after the return?
Mike
On Apr 5, 2015, at 9:12 AM, Aldo Davide
Sorry but I am having trouble understanding your post, but here's some information you might find useful:
* If you want to pass a callback to a C function, you need to use a FunPtr. In particular, you need to create a "wrapper" foreign import that will allow you to convert a haskell function to a FunPtr that can be then passed to C and called by C. The docs on FunPtr [1] explain how to do this.
* Ptr is not a data constructor, its a type constructor, so e.g. `Ptr CInt` is a valid type, but `Ptr 4` is not a valid expression. If you want to store a value in the heap and then create a pointer to it, you can use the `with` function [2]. So e.g. in `with 5 $ \p -> ...`, p is a `Ptr CInt`. Remember that `Ptr`s are to useful for passing callbacks though.
[1] https://hackage.haskell.org/package/base-4.8.0.0/docs/Foreign-Ptr.html#t:Fun... [2] https://hackage.haskell.org/package/base-4.8.0.0/docs/Foreign-Marshal-Utils....
Michael Jones, wrote:
I am having trouble figuring out how to pass callbacks to C.
Given the definition below it is not clear how to define a function and pass it. I tried:
getNumberOfRows :: CInt getNumberOfRows = 1
table <- wxcGridTableCreate getNumberOfRows…
but the compiler barks at me:
src/MainGui.hs:577:32: Not in scope: data constructor ‘Ptr’
even through I do the imports:
import Foreign import Foreign.C
There is also a _obj as the first value of wxcGridTableCreate and the callbacks, and I am not sure how to make a this* for it. I would have throughout that wxcGridTableCreate would return a Ptr.
The goal is to pass haskell functions into wxcGridTableCreate so the grid can call back to haskell.
Can someone show an example of just this one function, how to wrap a Ptr around it, and what to do with _obj?
DEFINITION
wxcGridTableCreate :: Ptr a -> Ptr b -> Ptr c -> Ptr d -> Ptr e -> Ptr f -> Ptr g -> Ptr h -> Ptr i -> Ptr j -> Ptr k -> Ptr l -> Ptr m -> Ptr n -> Ptr o -> Ptr p -> Ptr q -> IO (WXCGridTable ()) wxcGridTableCreate _obj _EifGetNumberRows _EifGetNumberCols _EifGetValue _EifSetValue _EifIsEmptyCell _EifClear _EifInsertRows _EifAppendRows _EifDeleteRows _EifInsertCols _EifAppendCols _EifDeleteCols _EifSetRowLabelValue _EifSetColLabelValue _EifGetRowLabelValue _EifGetColLabelValue = withObjectResult $ wx_ELJGridTable_Create _obj _EifGetNumberRows _EifGetNumberCols _EifGetValue _EifSetValue _EifIsEmptyCell _EifClear _EifInsertRows _EifAppendRows _EifDeleteRows _EifInsertCols _EifAppendCols _EifDeleteCols _EifSetRowLabelValue _EifSetColLabelValue _EifGetRowLabelValue _EifGetColLabelValue foreign import ccall "ELJGridTable_Create" wx_ELJGridTable_Create :: Ptr a -> Ptr b -> Ptr c -> Ptr d -> Ptr e -> Ptr f -> Ptr g -> Ptr h -> Ptr i -> Ptr j -> Ptr k -> Ptr l -> Ptr m -> Ptr n -> Ptr o -> Ptr p -> Ptr q -> IO (Ptr (TWXCGridTable ()))
typedef int _cdecl (*TGridGetInt)(void* _obj); typedef int _cdecl (*TGridIsEmpty)(void* _obj, int row, int col); typedef void* _cdecl (*TGridGetValue)(void* _obj, int row, int col); typedef void _cdecl (*TGridSetValue)(void* _obj, int row, int col, void* val); typedef void _cdecl (*TGridClear)(void* _obj); typedef int _cdecl (*TGridModify)(void* _obj, int pos, int num); typedef int _cdecl (*TGridMultiModify)(void* _obj, int num); typedef void _cdecl (*TGridSetLabel)(void* _obj, int idx, void* val); typedef void* _cdecl (*TGridGetLabel)(void* _obj, int idx);
EWXWEXPORT(void*,ELJGridTable_Create)(void* self,void* _EifGetNumberRows,void* _EifGetNumberCols,void* _EifGetValue,void* _EifSetValue,void* _EifIsEmptyCell,void* _EifClear,void* _EifInsertRows,void* _EifAppendRows,void* _EifDeleteRows,void* _EifInsertCols,void* _EifAppendCols,void* _EifDeleteCols,void* _EifSetRowLabelValue,void* _EifSetColLabelValue,void* _EifGetRowLabelValue,void* _EifGetColLabelValue) { return (void*)new ELJGridTable (self,
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Quoth Michael Jones
The problem is newCWString creates a string that must be freed, and wxWidgets does not free it. This results in a memory leak.
In a real application, I'll probably store a String in a TVar so that some thread can keep it up to date. I could use other TVars to hold the CWString and free it each time a new value is created. But, it would be better if there was some way to guarantee it is freed, even with exceptions, etc. The best would be if when the function returns, it automatically freed the string.
Is there a way express the callback function so that it frees the string after the return?
Are you sure that's what you want? I may be misunderstanding "after the return" - to me, that sounds like right after your getValue callback. That would be approximately the same as freeing it within the callback, right after allocation and initialization. That's not ideal at all. You'll need to store the string in your application, it seems to me, and pass that value via the callback rather than allocating a new copy each time. Donn

Donn,
My intent was to hold the strings in a TVar, with a thread keeping it up to date, in this case, filtering, adding, etc.
I need to look at how TVar works. I assume that a read from a TVar produces a value, and if the read from TVar is done in the callback, the pointer has to be freed when the callback exits, or by the C++ code.
I also recall seeing some code in wxWidgets where after the callback to read is made, it calls another callback to set. It may be intended as a way to free memory. If every read is followed by a set, the set could could free the pointer.
Either way, the design has dynamic data getting updated by a thread at a rate of change much larger than human interaction (scrolling).
Mike
On Apr 6, 2015, at 10:47 AM, Donn Cave
Quoth Michael Jones
, The problem is newCWString creates a string that must be freed, and wxWidgets does not free it. This results in a memory leak.
In a real application, I'll probably store a String in a TVar so that some thread can keep it up to date. I could use other TVars to hold the CWString and free it each time a new value is created. But, it would be better if there was some way to guarantee it is freed, even with exceptions, etc. The best would be if when the function returns, it automatically freed the string.
Is there a way express the callback function so that it frees the string after the return?
Are you sure that's what you want? I may be misunderstanding "after the return" - to me, that sounds like right after your getValue callback. That would be approximately the same as freeing it within the callback, right after allocation and initialization. That's not ideal at all. You'll need to store the string in your application, it seems to me, and pass that value via the callback rather than allocating a new copy each time.
Donn _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Turns out Set is not called after Get.
So here is what I am thinking:
getValue :: TVar (ForeignPtr CWchar) -> Ptr CInt -> CInt -> CInt -> IO CWString
getValue ptr p r c = do
s <- if c == 0
then newCWString "Str 0"
else newCWString "Str 1"
sPtr <- newForeignPtr finalizerFree s
liftIO $ atomically $ writeTVar ptr sPtr
return s
Create a ForeignPtr and store it in a TVar. After the callback, the CWString will be inside the ForeignPtr until it is no longer referenced. On the second call, TVar will be given a new ForeignPtr, and the previous one will get collected, and finalizerFree will free the CWString.
The next step will be to generate the CWString out of another TVar, rather than the fixed string in the example.
There might be a way to get a Ptr to the original string rather than generating a new string, but I don’t know what goes on in the TVar, so I am suspect of holding a pointer to anything inside it. But with the above, I essentially copy the string and manage its collection.
Thoughts?
Mike
On Apr 6, 2015, at 11:35 AM, Michael Jones
Donn,
My intent was to hold the strings in a TVar, with a thread keeping it up to date, in this case, filtering, adding, etc.
I need to look at how TVar works. I assume that a read from a TVar produces a value, and if the read from TVar is done in the callback, the pointer has to be freed when the callback exits, or by the C++ code.
I also recall seeing some code in wxWidgets where after the callback to read is made, it calls another callback to set. It may be intended as a way to free memory. If every read is followed by a set, the set could could free the pointer.
Either way, the design has dynamic data getting updated by a thread at a rate of change much larger than human interaction (scrolling).
Mike
On Apr 6, 2015, at 10:47 AM, Donn Cave
wrote: Quoth Michael Jones
, The problem is newCWString creates a string that must be freed, and wxWidgets does not free it. This results in a memory leak.
In a real application, I'll probably store a String in a TVar so that some thread can keep it up to date. I could use other TVars to hold the CWString and free it each time a new value is created. But, it would be better if there was some way to guarantee it is freed, even with exceptions, etc. The best would be if when the function returns, it automatically freed the string.
Is there a way express the callback function so that it frees the string after the return?
Are you sure that's what you want? I may be misunderstanding "after the return" - to me, that sounds like right after your getValue callback. That would be approximately the same as freeing it within the callback, right after allocation and initialization. That's not ideal at all. You'll need to store the string in your application, it seems to me, and pass that value via the callback rather than allocating a new copy each time.
Donn _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
participants (3)
-
Aldo Davide
-
Donn Cave
-
Michael Jones