• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1193
  • Last Modified:

Compiling C code into a DLL for use in C#

Hello all,

I am trying to compile the standard files for iLBC (which is provided in C) into a DLL so that the files can be called in C#.  All of the files are located here: http://www.csee.usf.edu/~dgill/iLBC/iLBC.zip.

I have found a couple of sites that give some instructions but I am still having a problem compiling the code.  Here are the sites for reference: http://sig9.com/node/35 and http://www-users.cs.umn.edu/~mein/blender/plugins/dll.html.  Though I think the first link was more helpful.

I beleive the iLBC_encode.c and iLBC_decode.c are the only files that need to be modified, but this is the first time I have attempted to create a DLL, so I can't be certain of this.  I believe that I also need to add one or two (probably one) header file for creating the DLLs.

I need to call this code to convert a voice stream to iLBC for transmission in a Voice-over-Wifi application using PDAs with Windows Mobile 5.0.  The current code we have uses uncompressed WAV files to send the data, which means there is a significant impact on the latency.

If you need anymore information to assist please let me know.

There is an RFC in the zip file that explains how the process works.  The file was not created in Windows, so you may need something like Notepad2 (http://www.flos-freeware.ch/notepad2.html) to view it properly.  iLBC_test.c is a program to test the encode and decode functions on a single file.

  • 7
  • 6
1 Solution
Ok here's an example:
Here's a C file for building a DLL:
#include <windows.h>

int __declspec(dllexport) a_function(int a, int b) {
      return a+b ;

Now here's the C# side:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace use_c_cll
    class Program {
        public static extern int a_function(int a, int b);
        static void Main(string[] args)
              Console.WriteLine("C DLL return type = {0}\n", a_function(1, 2));

The DllImport imports the mentioned DLL and the line below is  a prototyp for the implemented function. Then you can simply call the function as
it it had been implemented in C#


and probalby the unsafe stuff also (if you are handling cursors). I guess it would be easier if the library has  a COM-Interface also.


pyroman1Author Commented:
Still doesn't compile fully.  Here is the error:
C:\Dev-Cpp\iLBC>gcc -shared -o iLBC_encode.dll iLBC_encode.o -Wl,--out-implib,libmessage.a
Creating library file: libmessage.a
iLBC_encode.o(.text+0x60):iLBC_encode.c: undefined reference to `ULP_30msTbl'
iLBC_encode.o(.text+0xb8):iLBC_encode.c: undefined reference to `ULP_20msTbl'
iLBC_encode.o(.text+0xf4):iLBC_encode.c: undefined reference to `lsfmeanTbl'
iLBC_encode.o(.text+0x112):iLBC_encode.c: undefined reference to `lsfmeanTbl'
iLBC_encode.o(.text+0x1a4):iLBC_encode.c: undefined reference to `hpInput'
iLBC_encode.o(.text+0x1d7):iLBC_encode.c: undefined reference to `LPCencode'
iLBC_encode.o(.text+0x260):iLBC_encode.c: undefined reference to `anaFilter'
iLBC_encode.o(.text+0x282):iLBC_encode.c: undefined reference to `FrameClassify'

iLBC_encode.o(.text+0x471):iLBC_encode.c: undefined reference to `StateSearchW'
iLBC_encode.o(.text+0x4cd):iLBC_encode.c: undefined reference to `StateConstruct
iLBC_encode.o(.text+0x5ad):iLBC_encode.c: undefined reference to `stMemLTbl'
iLBC_encode.o(.text+0x5bc):iLBC_encode.c: undefined reference to `stMemLTbl'
iLBC_encode.o(.text+0x607):iLBC_encode.c: undefined reference to `iCBSearch'
iLBC_encode.o(.text+0x61e):iLBC_encode.c: undefined reference to `stMemLTbl'
iLBC_encode.o(.text+0x62d):iLBC_encode.c: undefined reference to `stMemLTbl'
iLBC_encode.o(.text+0x671):iLBC_encode.c: undefined reference to `iCBConstruct'
iLBC_encode.o(.text+0x7b6):iLBC_encode.c: undefined reference to `stMemLTbl'
iLBC_encode.o(.text+0x7c5):iLBC_encode.c: undefined reference to `stMemLTbl'
iLBC_encode.o(.text+0x7fe):iLBC_encode.c: undefined reference to `iCBSearch'
iLBC_encode.o(.text+0x815):iLBC_encode.c: undefined reference to `stMemLTbl'
iLBC_encode.o(.text+0x824):iLBC_encode.c: undefined reference to `stMemLTbl'
iLBC_encode.o(.text+0x856):iLBC_encode.c: undefined reference to `iCBConstruct'
iLBC_encode.o(.text+0x9bb):iLBC_encode.c: undefined reference to `memLfTbl'
iLBC_encode.o(.text+0x9d2):iLBC_encode.c: undefined reference to `memLfTbl'
iLBC_encode.o(.text+0xa4f):iLBC_encode.c: undefined reference to `iCBSearch'
iLBC_encode.o(.text+0xa6c):iLBC_encode.c: undefined reference to `memLfTbl'
iLBC_encode.o(.text+0xa83):iLBC_encode.c: undefined reference to `memLfTbl'
iLBC_encode.o(.text+0xaf9):iLBC_encode.c: undefined reference to `iCBConstruct'
iLBC_encode.o(.text+0xdf1):iLBC_encode.c: undefined reference to `memLfTbl'
iLBC_encode.o(.text+0xe08):iLBC_encode.c: undefined reference to `memLfTbl'
iLBC_encode.o(.text+0xe78):iLBC_encode.c: undefined reference to `iCBSearch'
iLBC_encode.o(.text+0xe95):iLBC_encode.c: undefined reference to `memLfTbl'
iLBC_encode.o(.text+0xeac):iLBC_encode.c: undefined reference to `memLfTbl'
iLBC_encode.o(.text+0xf15):iLBC_encode.c: undefined reference to `iCBConstruct'
iLBC_encode.o(.text+0x100f):iLBC_encode.c: undefined reference to `index_conv_en
iLBC_encode.o(.text+0x1116):iLBC_encode.c: undefined reference to `packsplit'
iLBC_encode.o(.text+0x1158):iLBC_encode.c: undefined reference to `dopack'
iLBC_encode.o(.text+0x11d7):iLBC_encode.c: undefined reference to `packsplit'
iLBC_encode.o(.text+0x120d):iLBC_encode.c: undefined reference to `dopack'
iLBC_encode.o(.text+0x1288):iLBC_encode.c: undefined reference to `packsplit'
iLBC_encode.o(.text+0x12c1):iLBC_encode.c: undefined reference to `dopack'
iLBC_encode.o(.text+0x133c):iLBC_encode.c: undefined reference to `packsplit'
iLBC_encode.o(.text+0x1375):iLBC_encode.c: undefined reference to `dopack'
iLBC_encode.o(.text+0x1424):iLBC_encode.c: undefined reference to `packsplit'
iLBC_encode.o(.text+0x145d):iLBC_encode.c: undefined reference to `dopack'
iLBC_encode.o(.text+0x154a):iLBC_encode.c: undefined reference to `packsplit'
iLBC_encode.o(.text+0x1590):iLBC_encode.c: undefined reference to `dopack'
iLBC_encode.o(.text+0x167d):iLBC_encode.c: undefined reference to `packsplit'
iLBC_encode.o(.text+0x16c3):iLBC_encode.c: undefined reference to `dopack'
iLBC_encode.o(.text+0x182c):iLBC_encode.c: undefined reference to `packsplit'
iLBC_encode.o(.text+0x1882):iLBC_encode.c: undefined reference to `dopack'
iLBC_encode.o(.text+0x19f8):iLBC_encode.c: undefined reference to `packsplit'
iLBC_encode.o(.text+0x1a4e):iLBC_encode.c: undefined reference to `dopack'
iLBC_encode.o(.text+0x1a9d):iLBC_encode.c: undefined reference to `dopack'
collect2: ld returned 1 exit status

I only changed the iLBC_encode.c file.  Here are the changes:
//   #ifndef BUILD_DLL
   /* DLL export */
   #define EXPORT __declspec(dllexport)
//   #else
//   /* EXE import */
//   #define EXPORT __declspec(dllimport)
//   #endif
***** This was inserted directly above the include's ************

Changed this:
   void iLBC_encode(
to this:
   EXPORT void iLBC_encode(

well you are missing some library to which you have to link your program. However that has nothing to do with the first question.
Network Scalability - Handle Complex Environments

Monitor your entire network from a single platform. Free 30 Day Trial Now!

pyroman1Author Commented:
The error message is exactly the same as when I used a dll.h file and put
   #ifndef BUILD_DLL
   /* DLL export */
   #define EXPORT __declspec(dllexport)
   /* EXE import */
   #define EXPORT __declspec(dllimport)
in it.  The only difference is I used your suggestion by getting rid of the header file (not exactly a suggestion, but rather an implication).

I suppose technically I didn't really ask a question since none of my sentences actually had a question mark, but the question does remain.  How do I need to modify the iLBC source files to allow compilation into a DLL?  The documents available online only provide details for very simple single function programs, yet iLBC is very complex including several C and H files to perform its functions.  Do I need to add the EXPORT macro to every function and every C file that will be used?  Do I need to make a DLL for every C file?  Another possible question is: Has anyone ever modified the iLBC source files for this purpose and are they willing to provide the source code or some guidance?
Well if you are on Windows you have either to
- decorate the name of the funciont to be exported with EXPORT, but you also ahve to define the -DBUILD_DLL preprocessor directive while compiling
- or you write a so called .def file in which you write down the function to be exported.

Howerve that has nothing to do with the missing symbols that is a linker problem. It's not sufficient to just include some header files but also to link against the proper libraries.

And your command line for building a shared library is wrong also. If you insist on using gcc please search for some topic which explains on how to build shared libraris on Windows.

You first should try wheter you can compile the source I presented into a DLL. Then try to use the DLL. After you know how to build and use a DLL you can try to compile the sources you like. If you have no idea on how to do that it might be a good idea asking someone who knows to do that for you. It might be easy it might take quite some effort. I can't tell.

pyroman1Author Commented:
OK, I complied your code (which is basically a very simple program that adds instead of displaying Hello World like the examples I referenced in my OP).  It compiles fine.  This still doesn't help me with compiling complex code with several functions.  At this point I am only concerned with building the DLL, I'll worry about using it later.  The reason I posted here was in hopes of finding someone that knows how to do it, since there are no resources that I can find in a first or second page search on google.  Plenty of searches come up with very simple DLL creation, I can't come up with a multiple source example.
pyroman1Author Commented:
After about an hour staring at the error I finally figured out what the problem was; because I was using multiple source files I needed to include all of them in the compilation separately.

This is what I did to create the encode DLL:
gcc -c -DBUILD_DLL iLBC_encode.c LPCencode.c FrameClassify.c StateSearchW.c StateConstructW.c helpfun.c constants.c packing.c iCBSearch.c iCBConstruct.c hpInput.c anaFilter.c syntFilter.c ...(etc including every file that had a function used in one of these C files)

Once this created all the .o files I ran the following command:
gcc -shared -o iLBC_encode.dll iLBC_encode.o LPCencode.o FrameClassify.o StateSearchW.o StateConstructW.o helpfun.o constants.o packing.o iCBSearch.o iCBConstruct.o hpInput.o anaFilter.o syntFilter.o ...(etc including all .o files) -Wl,--out-implib,libencode.a

Next I compile the object code for iLBC_test.c:
gcc -c iLBC_test.c

This code then compiled correctly and I tested it by compiling against the iLBC_test.c file using:
gcc -o test.exe iLBC_test.o iLBC_encode.dll

This ran perfectly using a test.wav file.

Here are the modifications I made:
###in iLBC_encode.h###
#ifdef BUILD_DLL
/* DLL export */
#define EXPORT __declspec(dllexport)
/* EXE import */
#define EXPORT __declspec(dllimport)


added EXPORT before each function

###in iLBC_encode.c###
#include "iLBC_encode.h"

added EXPORT before each function

Similar modifcations were made to the iLBC_decode.c and .h files.  For every error (for example: undefined reference to `ULP_30msTbl') look for what .c file that function or variable is first declared and added it to the list above (in this example it is referenced first in constants.c).  Make sure every .c file in the first command has an appropriate .o file in the second command.

Hopefully this will help someone else to create DLLs from the iLBC source code.  Now on to how to make the appropriate modifications to the original code I was provided to use the DLLs and encode and decode the data.
Well the usual way to build such stuff is using a Makefile. I bet something like that was available for this software also.
However this has nothing to do with the original question. One must assume that one knows how to build a shared library, how build a C project and the like. You did not have shown that you have no idea about that...

pyroman1Author Commented:
Normally I use an IDE and I don't worry about makefiles.  Because of the nature of my request (i.e. How do I compile the iLBC source files, provided here: http://www.csee.usf.edu/~dgill/iLBC/iLBC.zip, into a DLL?) I couldn't use an IDE.  At least not by any of the methods that I found online, most notably http://sig9.com/node/35, and subsequently used.
You can use an IDE also but then you have to know how to generate projects in it. However there should have been some sort of README or INSTALL file there, which should have give at least some hints.

Well I answered the question of how to build a DLl to be used with C#. It's not my fault if that was not the "real" question.

pyroman1Author Commented:
Actually I asked how to compile the iLBC files in the link I provided into a DLL.  I also provided links that explained how to create a DLL out of a single C file into a Hello World program.  What you provided was the same explanation with the one difference being that the single C file added two numbers rather than displaying Hello World.  I also explained that the instructions for creating a DLL from a single C file did not help me with creating a DLL from multiple source files.  I do respectfully disagree that giving me the same instructions as the link in my question,http://sig9.com/node/35 (of course modifying "Hello World" to add two numbers), constitutes answering the question.  I also explained in every subsequent post that the error message was the same as before I posted the question to help clarify my question if it wasn't easy to understand.

The only portion that was even remotely correct for this paricular situation was that the command line for building the DLL was incorrect; however, the only information that was provided was it "is wrong."  I had to figure out what was wrong and how to fix it.  There was no link to a website that explained how to do it nor any advice provided.  I knew something was wrong, it wouldn't compile.  Saying it "is wrong" did not actually help at all, there was not even a mention as to how it was wrong.

I would not even see how this could constitute any of the grades offered for a solution.

A: The Expert(s) either provided you with a thorough answer or they provided you with a link to information that thoroughly answered your question. An "A" can also be given to any answer that you found informative or enlightening beyond the direct question that you asked.
Obviously this did not occur as I had to figure it out myself, the information provided was almost identical to what I provided in my question.

B: The Expert(s) provided an acceptable solution, or a link to an acceptable solution, that you were able to use, although you may have needed a bit more information to complete the task.
Again, the information and links provided were of no more help than what I provided originally.

C: Because Experts' reliability are often judged by their grading records, many Experts would like the opportunity to clarify if you have questions about their solutions. If you have given the Expert(s) ample time to respond to your clarification posts and you have responded to each of their posts providing requested information; or if the answers, after clarification, lack finality or do not completely address the issue presented, then a "C" grade is an option. You also have the option here of just asking Community Support to delete the question.
This would be the closest option as the answer did not completely address the issue; however, as the answer provided no new information and I did solve the issue on my own, I asked to have points refunded rather than deleted so others may have the fully disclosed information that I discovered at their disposal.
then you should put you question like this:
I have not idea on how to build a DLL, how to do that?

You question how to make use of DLL to be called from C#.

PAQd, 500 points refunded.

CS Moderator
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Managing Security Policy in a Changing Environment

The enterprise network environment is evolving rapidly as companies extend their physical data centers to embrace cloud computing and software-defined networking. This new reality means that the challenge of managing the security policy is much more dynamic and complex.

  • 7
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now