Skip to content

Commit

Permalink
Redefine opaque types as pointers to structs.
Browse files Browse the repository at this point in the history
Warning: This may break source compatibility!

This fixes casting-related errors in the C++ wrapper related to
passing a lo::ServerThread object to lo::Address::send_from, see
radarsat1#101

To summarize, the C++ template cannot differentiate between lo_server
and lo_server_thread because they are both (void*), and therefore
performs the wrong cast.  This can be fixed by making these opaque
types pointers to different types instead of all pointing to void.

It could be possible to redefine just these types, but this patch
takes this to the full extent and redefines all the opaque pointers so
that they are different types, to avoid any potential similar issues.

It is more correct, but could lead to incompatibility with older code,
particularly because it redefines the lo_method_handler prototype.
  • Loading branch information
radarsat1 committed Aug 22, 2020
1 parent ea6b814 commit 2c1ef1c
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 26 deletions.
16 changes: 8 additions & 8 deletions examples/example_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ int done = 0;
void error(int num, const char *m, const char *path);

int generic_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);
int argc, lo_message data, void *user_data);

int foo_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);
int argc, lo_message data, void *user_data);

int blobtest_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);
int argc, lo_message data, void *user_data);

int quit_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);
int argc, lo_message data, void *user_data);

int main()
{
Expand Down Expand Up @@ -79,7 +79,7 @@ void error(int num, const char *msg, const char *path)
/* catch any incoming messages and display them. returning 1 means that the
* message has not been fully handled and the server should try other methods */
int generic_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data)
int argc, lo_message data, void *user_data)
{
int i;

Expand All @@ -96,7 +96,7 @@ int generic_handler(const char *path, const char *types, lo_arg ** argv,
}

int foo_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data)
int argc, lo_message data, void *user_data)
{
/* example showing pulling the argument values out of the argv array */
printf("%s <- f:%f, i:%d\n\n", path, argv[0]->f, argv[1]->i);
Expand All @@ -106,7 +106,7 @@ int foo_handler(const char *path, const char *types, lo_arg ** argv,
}

int blobtest_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data)
int argc, lo_message data, void *user_data)
{
/* example showing how to get data for a blob */
int i, size = argv[0]->blob.size;
Expand Down Expand Up @@ -136,7 +136,7 @@ int blobtest_handler(const char *path, const char *types, lo_arg ** argv,
}

int quit_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data)
int argc, lo_message data, void *user_data)
{
done = 1;
printf("quiting\n\n");
Expand Down
8 changes: 4 additions & 4 deletions examples/example_tcp_echo_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ int count = 0;
void error(int num, const char *m, const char *path);

int echo_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);
int argc, lo_message data, void *user_data);

int quit_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);
int argc, lo_message data, void *user_data);

void ctrlc(int sig)
{
Expand Down Expand Up @@ -114,7 +114,7 @@ void error(int num, const char *msg, const char *path)
/* catch any incoming messages, display them, and send them
* back. */
int echo_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data)
int argc, lo_message data, void *user_data)
{
int i;
lo_message m = (lo_message)data;
Expand Down Expand Up @@ -159,7 +159,7 @@ int echo_handler(const char *path, const char *types, lo_arg ** argv,
}

int quit_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data)
int argc, lo_message data, void *user_data)
{
done = 1;
printf("quitting\n\n");
Expand Down
12 changes: 6 additions & 6 deletions examples/nonblocking_server_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ int done = 0;
void error(int num, const char *m, const char *path);

int generic_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);
int argc, lo_message data, void *user_data);

int foo_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);
int argc, lo_message data, void *user_data);

int quit_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);
int argc, lo_message data, void *user_data);

void read_stdin(void);

Expand Down Expand Up @@ -151,7 +151,7 @@ void error(int num, const char *msg, const char *path)
/* catch any incoming messages and display them. returning 1 means that the
* message has not been fully handled and the server should try other methods */
int generic_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data)
int argc, lo_message data, void *user_data)
{
int i;

Expand All @@ -168,7 +168,7 @@ int generic_handler(const char *path, const char *types, lo_arg ** argv,
}

int foo_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data)
int argc, lo_message data, void *user_data)
{
/* example showing pulling the argument values out of the argv array */
printf("%s <- f:%f, i:%d\n\n", path, argv[0]->f, argv[1]->i);
Expand All @@ -178,7 +178,7 @@ int foo_handler(const char *path, const char *types, lo_arg ** argv,
}

int quit_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data)
int argc, lo_message data, void *user_data)
{
done = 1;
printf("quiting\n\n");
Expand Down
2 changes: 1 addition & 1 deletion lo/lo_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
std::unique_ptr<handler>(new handler_type<r ht>(h))); \
lo_method m = _add_method(path, types, \
[](const char *path, const char *types, \
lo_arg **argv, int argc, void *msg, \
lo_arg **argv, int argc, lo_message msg, \
void *data)->int \
{ \
r1 (*static_cast<handler_type<r ht>*>(data)) args; \
Expand Down
14 changes: 7 additions & 7 deletions lo/lo_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,22 @@ extern "C" {
*
* Created by calls to lo_address_new() or lo_address_new_from_url().
*/
typedef void *lo_address;
typedef struct lo_address_ {} *lo_address;

/**
* \brief A object to store an opaque binary data object.
*
* Can be passed over OSC using the 'b' type. Created by calls to lo_blob_new().
*/
typedef void *lo_blob;
typedef struct lo_blob_ {} *lo_blob;

/**
* \brief A low-level object used to represent messages passed over OSC.
*
* Created by calls to lo_message_new(), arguments can be added with calls to
* lo_message_add_*().
*/
typedef void *lo_message;
typedef struct lo_message_ {} *lo_message;

/**
* \brief A low-level object used to represent bundles of messages passed over
Expand All @@ -66,30 +66,30 @@ typedef void *lo_message;
* Created by calls to lo_bundle_new(), messages can be added with calls to
* lo_bundle_add_message().
*/
typedef void *lo_bundle;
typedef struct lo_bundle_ {} *lo_bundle;

/**
* \brief An object representing an method on a server.
*
* Returned by calls to lo_server_thread_add_method() and
* lo_server_add_method().
*/
typedef void *lo_method;
typedef struct lo_method_ {} *lo_method;

/**
* \brief An object representing an instance of an OSC server.
*
* Created by calls to lo_server_new(). If you wish to have the server
* operate in a background thread, use lo_server_thread instead.
*/
typedef void *lo_server;
typedef struct lo_server_ {} *lo_server;

/**
* \brief An object representing a thread containing an OSC server.
*
* Created by calls to lo_server_thread_new().
*/
typedef void *lo_server_thread;
typedef struct lo_server_thread_ {} *lo_server_thread;

/**
* \brief A callback function to receive notification of an error in a server or
Expand Down

0 comments on commit 2c1ef1c

Please sign in to comment.