Solved

How to debug a DLL using MinGW?

Posted on 2008-10-06
13
1,991 Views
Last Modified: 2013-11-23
I'm writing an application in Delphi (using D2005) calling a DLL written in C using MinGW. So far it works fine, BUT I would like to debug the DLL using MinGW. I have added a host application and when started with Run or Debug works, BUT when I add a breakpoint (in HelloWorld) the host app starts and breakpoint is not reached. What I am doing wrong?

Thanks
Delphi Code-------------------------------------------------------------

program CallMyLib;
 

{$APPTYPE CONSOLE}
 

uses

  Dialogs,

  Windows,

  SysUtils;
 

type

TMyProc = procedure( a : integer); stdcall;

var

i : Integer;

DLLHandle: THandle;

MyProc : TMyProc;

begin

DLLHandle := LoadLibrary('mylib.dll');

if DLLHandle >0 then

  begin

  @MyProc := GetProcAddress(DLLHandle, 'HelloWorld');

    if Assigned(MyProc) then

      begin

        MyProc( 11 );

      //ShowMessage(IntToStr(i));

      end;

  end;                        //mystring

  FreeLibrary(DLLHandle);

end.
 

DLL.h-------------------------------------------------------------------

#ifndef _DLL_H_

#define _DLL_H_
 

#if BUILDING_DLL

# define DLLIMPORT __declspec (dllexport)

#else /* Not BUILDING_DLL */

# define DLLIMPORT __declspec (dllimport)

#endif /* Not BUILDING_DLL */
 
 

DLLIMPORT void HelloWorld (int a);
 
 

#endif /* _DLL_H_ */
 

DLLMain.c---------------------------------------------------------------

#include "dll.h"

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>
 

DLLIMPORT void HelloWorld (int a)

{

    MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);

}
 
 

BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,

                       DWORD reason        /* Reason this function is being called. */ ,

                       LPVOID reserved     /* Not used. */ )

{

    switch (reason)

    {

      case DLL_PROCESS_ATTACH:

        break;
 

      case DLL_PROCESS_DETACH:

        break;
 

      case DLL_THREAD_ATTACH:

        break;
 

      case DLL_THREAD_DETACH:

        break;

    }
 

    /* Returns TRUE on success, FALSE on failure */

    return TRUE;

}

Open in new window

0
Comment
Question by:zordes
  • 7
  • 6
13 Comments
 
LVL 5

Expert Comment

by:libin_v
ID: 22656873
You could use gdb, there are 2 ways to debug DLL. (Note: I have always tried with the dll and exe in the same directory only)

1. Before running the program

$ gdb <executable>
> dll-symbols <dllname.dll>
> list <function-to-debug>
. 120      void function_to_debug ( )
. 121      {
. 122                  g_a = g_b + g_c;
.
.
.
> b 122
> run

2. After Executing

$gdb <executable>
(gdb) b main
(gdb) run
(gdb) b <function-to-debug>
(gdb) continue
0
 

Author Comment

by:zordes
ID: 22657137
Thank You
I tried it, but I'm receiving the following error message..


E:\Programme\Dev-Cpp\Examples\zd>..\..\bin\gdb CallMyLib.exe

GNU gdb 5.2.1

Copyright 2002 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "i686-pc-mingw32"...(no debugging symbols found)...

(gdb) dll-symbols MyLib.dll

(gdb) list HelloWorld

3       #include <windows.h>

4       #include <stdio.h>

5       #include <stdlib.h>

6

7       DLLIMPORT void HelloWorld (int a)

8       {

9           MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);

10      }

11

12

(gdb) b 9

Breakpoint 1 at 0x625011d6: file dllmain.c, line 9.

(gdb) run

Starting program: E:\Programme\Dev-Cpp\Examples\zd/CallMyLib.exe

warning: Cannot insert breakpoint 1:

Cannot access memory at address 0x625011d6

Open in new window

0
 

Author Comment

by:zordes
ID: 22657386
I also tried the second approach. Because I have written my application with delphi there is no main routine, so I am getting an error message, please see attached code snippet.
E:\Programme\Dev-Cpp\Examples\zd>..\..\bin\gdb CallMyLib.exe

GNU gdb 5.2.1

Copyright 2002 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "i686-pc-mingw32"...(no debugging symbols found)...

(gdb) b main

No symbol table is loaded.  Use the "file" command.

(gdb)

Open in new window

0
 
LVL 5

Expert Comment

by:libin_v
ID: 22657741
Does you application run without arguments? If not use

set args argument1 argument2

before the dll-symbols
0
 

Author Comment

by:zordes
ID: 22657864
No, not at all.
Please refer to the first code-snippet. It's a simple delphi application. Maybe this is a problem.

Thanks
0
 
LVL 5

Expert Comment

by:libin_v
ID: 22659220
Even I encounter the error using Method 2

But try Method 1. Attached is my run log

-------------- Using Method 2 ---------------

D:\Work\EE\23792765-PascalDLLDebug>gdb PascalDLLDebug.exe

GNU gdb 5.2.1

Copyright 2002 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "i686-pc-mingw32"...

(gdb) b 1

Breakpoint 1 at $401430: file PascalDLLDebug.pas, line 1.

(gdb) r

Starting program: D:\Work\EE\23792765-PascalDLLDebug/PascalDLLDebug.exe
 

Breakpoint 1, main () at PascalDLLDebug.pas:17

17      begin

(gdb) n

main () at PascalDLLDebug.pas:18

18      DLLHandle := LoadLibrary('PascalDLLDebug.dll');

(gdb) n

19      if DLLHandle >0 then

(gdb) n

21        SomeHandle := GetProcAddress(DLLHandle, 'HelloWorld');

(gdb) n

22          if Assigned(SomeHandle) then

(gdb) n

24                 MyProc := TMyProc(SomeHandle);

(gdb) n

25              MyProc( 11 );

(gdb) s

HelloWorld (a=11) at DLLMain.c:8

8           MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);
 

Current language:  auto; currently c

(gdb) n

9       }

(gdb) n

main () at PascalDLLDebug.pas:29

29        FreeLibrary(DLLHandle);

Current language:  auto; currently pascal

(gdb) n

30      end.

(gdb) n
 

Program exited normally.

(gdb) n

The program is not being run.

(gdb)
 

------------- Error with method 2 ------------------

D:\Work\EE\23792765-PascalDLLDebug>gdb PascalDLLDebug.exe

GNU gdb 5.2.1

Copyright 2002 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "i686-pc-mingw32"...

(gdb) dll-symbols PascalDLLDebug.dll

(gdb) list HelloWorld

2       #include <windows.h>

3       #include <stdio.h>

4       #include <stdlib.h>

5

6       DLLIMPORT void HelloWorld (int a)

7       {

8           MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);
 

9       }

10

11

(gdb) b 8

Breakpoint 1 at $69001196: file DLLMain.c, line 8.

(gdb) run

Starting program: D:\Work\EE\23792765-PascalDLLDebug/PascalDLLDebug.exe

warning: Cannot insert breakpoint 1:

Cannot access memory at address $69001196

(gdb) quit

The program is running.  Exit anyway? (y or n) y

Open in new window

0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 5

Expert Comment

by:libin_v
ID: 22659343
You get the Error that cannot insert breakpoint because gdb can insert breakpoints to an unloaded binary.

Attached is sample run..

However, you can still insert breakpoints into unloaded binary with "pending setting on", which is actual default feature. But there is a bug with this http://sourceware.org/ml/gdb-patches/2008-04/msg00076.html

Once this bug is fixed.. you could use method 1
D:\Work\EE\23792765-PascalDLLDebug>gdb PascalDLLDebug.exe

GNU gdb 5.2.1

Copyright 2002 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "i686-pc-mingw32"...

(gdb) dll-symbols  PascalDLLDebug.dll

(gdb) list

9       type

10      TMyProc = procedure( a : LongInt); stdcall;

11      var

12      i : Integer;

13      DLLHandle: THandle;

14      MyProc : TMyProc;

15      SomeHandle : Pointer;

16      //MyProc: procedure (X: LongInt); {$IFDEF WIN32} stdcall; {$ENDIF}

17      begin

18      DLLHandle := LoadLibrary('PascalDLLDebug.dll');

(gdb) b 18

Breakpoint 1 at $401438: file PascalDLLDebug.pas, line 18.

(gdb) r

Starting program: D:\Work\EE\23792765-PascalDLLDebug/PascalDLLDebug.exe
 

Breakpoint 1, main () at PascalDLLDebug.pas:18

18      DLLHandle := LoadLibrary('PascalDLLDebug.dll');

(gdb) n

19      if DLLHandle >0 then

(gdb) list HelloWorld

2       #include <windows.h>

3       #include <stdio.h>

4       #include <stdlib.h>

5

6       DLLIMPORT void HelloWorld (int a)

7       {

8           MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);
 

9       }

10

11

(gdb) b 8

Breakpoint 2 at $69001196: file DLLMain.c, line 8.

(gdb) c

Continuing.
 

Breakpoint 2, HelloWorld (a=11) at DLLMain.c:8

8           MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);
 

Current language:  auto; currently c

(gdb) c

Continuing.
 

Program exited normally.

(gdb)

Open in new window

0
 

Author Comment

by:zordes
ID: 22666485
Thanks for your prompt answer.

I can't use the first method, because my application does not have debug symbols, please refer to code snippet.
I am going to install the newest gdb 6.8 and try the second method.
F:\temp\zd\zd>gdb

GNU gdb 6.3

Copyright 2004 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "i686-pc-mingw32".

(gdb) file CallMyLib.exe

Reading symbols from F:\temp\zd\zd/CallMyLib.exe...(no debugging symbols found)...done.

(gdb)

Open in new window

0
 

Author Comment

by:zordes
ID: 22668454
I have installed the newest version of gdb 6.8.3, but (using list method) still does not work.
I did not try the patcht, because to make the whole gdb needs some time.
I would like to use your Method 1, but can not find out why gdb can not understand my symbol table?
I built my application with Delphi 5.5 but still getting the same error.
Could you send me your delphi project?
Thanks
0
 
LVL 5

Accepted Solution

by:
libin_v earned 250 total points
ID: 22669674
I am totally new to Delphi, I used Lazuras with Free Pascal Compiler please find attached the project files

Basically compiling the Pascal with the following command

D:\Tools\lazarus\fpc\2.2.0\bin\i386-win32\fpc.exe -S2cgi -OG1 -gl -vewnhi -l -Fu. -oPascalDLLDebug.exe PascalDLLDebug.pas

Use -g to generate debug info


You need to give me 500 points for this :)
------------------- DLL.h ----------------------------
 

#ifndef _DLL_H_

#define _DLL_H_

 

#if BUILDING_DLL

# define DLLIMPORT __declspec (dllexport)

#else /* Not BUILDING_DLL */

# define DLLIMPORT __declspec (dllimport)

#endif /* Not BUILDING_DLL */

 

 

DLLIMPORT void HelloWorld (int a);

 

 

#endif /* _DLL_H_ *
 

---------------------- DLLMain.c --------------------------

#include "dll.h"

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

 

DLLIMPORT void HelloWorld (int a)

{

    MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);

}

 

 

BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,

                       DWORD reason        /* Reason this function is being called. */ ,

                       LPVOID reserved     /* Not used. */ )

{

    switch (reason)

    {

      case DLL_PROCESS_ATTACH:

        break;

 

      case DLL_PROCESS_DETACH:

        break;

 

      case DLL_THREAD_ATTACH:

        break;

 

      case DLL_THREAD_DETACH:

        break;

    }

 

    /* Returns TRUE on success, FALSE on failure */

    return TRUE;

}
 

------------ Makefile.win ----------------------------------

# Project: Project1

# Makefile created by Dev-C++ 4.9.9.2
 

CPP  = D:/Tools/Mingw/bin/g++.exe

CC   = D:/Tools/Mingw/bin/gcc.exe

WINDRES = D:/Tools/Mingw/bin/windres.exe

RES  = 

OBJ  = DLLMain.o $(RES)

LINKOBJ  = DLLMain.o $(RES)

LIBS =  --no-export-all-symbols --add-stdcall-alias 

INCS = 

CXXINCS = 

BIN  = PascalDLLDebug.dll

CXXFLAGS = $(CXXINCS) -DBUILDING_DLL=1  -g

CFLAGS = $(INCS) -DBUILDING_DLL=1  -g

RM = rm -f
 

.PHONY: all all-before all-after clean clean-custom
 

all: all-before PascalDLLDebug.dll all-after
 
 

clean: clean-custom

	${RM} $(OBJ) $(BIN)
 

DLLWRAP=D:/Tools/Mingw/bin/dllwrap.exe

DEFFILE=libPascalDLLDebug.def

STATICLIB=libPascalDLLDebug.a
 

$(BIN): $(LINKOBJ)

	$(DLLWRAP) --output-def $(DEFFILE) --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
 

DLLMain.o: DLLMain.c

	$(CC) -c DLLMain.c -o DLLMain.o $(CFLAGS)
 

--------------- PascalDLLDebug.compiled ---------------

<?xml version="1.0"?>

<CONFIG>

  <Compiler Value="D:\Tools\lazarus\fpc\2.2.0\bin\i386-win32\fpc.exe" Date="930002333"/>

  <Params Value=" -S2cgi -OG1 -gl -vewnhi -l -Fu. -oPascalDLLDebug.exe PascalDLLDebug.pas"/>

</CONFIG>
 

------------------ PascalDLLDebug.lpi (Lazurus Project File) -------------
 

<?xml version="1.0"?>

<CONFIG>

  <ProjectOptions>

    <PathDelim Value="\"/>

    <Version Value="6"/>

    <General>

      <Flags>

        <MainUnitHasUsesSectionForAllUnits Value="False"/>

        <MainUnitHasCreateFormStatements Value="False"/>

        <MainUnitHasTitleStatement Value="False"/>

      </Flags>

      <MainUnit Value="0"/>

      <TargetFileExt Value=".exe"/>

      <ActiveEditorIndexAtStart Value="0"/>

    </General>

    <VersionInfo>

      <ProjectVersion Value=""/>

      <Language Value=""/>

      <CharSet Value=""/>

    </VersionInfo>

    <PublishOptions>

      <Version Value="2"/>

      <IgnoreBinaries Value="False"/>

      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>

      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>

    </PublishOptions>

    <RunParams>

      <local>

        <FormatVersion Value="1"/>

        <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>

      </local>

    </RunParams>

    <Units Count="1">

      <Unit0>

        <Filename Value="PascalDLLDebug.pas"/>

        <IsPartOfProject Value="True"/>

        <UnitName Value="CallMyLib"/>

        <CursorPos X="44" Y="25"/>

        <TopLine Value="5"/>

        <EditorIndex Value="0"/>

        <UsageCount Value="20"/>

        <Loaded Value="True"/>

      </Unit0>

    </Units>

    <JumpHistory Count="28" HistoryIndex="27">

      <Position1>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="1" Column="23" TopLine="1"/>

      </Position1>

      <Position2>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="6" Column="10" TopLine="1"/>

      </Position2>

      <Position3>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="8" Column="11" TopLine="1"/>

      </Position3>

      <Position4>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="23" Column="48" TopLine="1"/>

      </Position4>

      <Position5>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="8" Column="11" TopLine="1"/>

      </Position5>

      <Position6>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="5" Column="1" TopLine="1"/>

      </Position6>

      <Position7>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="6" Column="1" TopLine="1"/>

      </Position7>

      <Position8>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="15" Column="25" TopLine="1"/>

      </Position8>

      <Position9>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="8" Column="1" TopLine="1"/>

      </Position9>

      <Position10>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="19" Column="3" TopLine="2"/>

      </Position10>

      <Position11>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="21" Column="6" TopLine="4"/>

      </Position11>

      <Position12>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="15" Column="3" TopLine="4"/>

      </Position12>

      <Position13>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="21" Column="5" TopLine="4"/>

      </Position13>

      <Position14>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="19" Column="5" TopLine="1"/>

      </Position14>

      <Position15>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="16" Column="30" TopLine="3"/>

      </Position15>

      <Position16>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="6" Column="1" TopLine="1"/>

      </Position16>

      <Position17>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="20" Column="63" TopLine="3"/>

      </Position17>

      <Position18>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="15" Column="3" TopLine="3"/>

      </Position18>

      <Position19>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="20" Column="53" TopLine="3"/>

      </Position19>

      <Position20>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="10" Column="33" TopLine="3"/>

      </Position20>

      <Position21>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="20" Column="3" TopLine="3"/>

      </Position21>

      <Position22>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="24" Column="10" TopLine="3"/>

      </Position22>

      <Position23>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="21" Column="17" TopLine="4"/>

      </Position23>

      <Position24>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="15" Column="21" TopLine="4"/>

      </Position24>

      <Position25>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="24" Column="9" TopLine="4"/>

      </Position25>

      <Position26>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="25" Column="15" TopLine="4"/>

      </Position26>

      <Position27>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="24" Column="29" TopLine="5"/>

      </Position27>

      <Position28>

        <Filename Value="PascalDLLDebug.pas"/>

        <Caret Line="30" Column="1" TopLine="5"/>

      </Position28>

    </JumpHistory>

  </ProjectOptions>

  <CompilerOptions>

    <Version Value="5"/>

    <PathDelim Value="\"/>

    <CodeGeneration>

      <Generate Value="Faster"/>

    </CodeGeneration>

    <Other>

      <CompilerPath Value="$(CompPath)"/>

    </Other>

  </CompilerOptions>

  <Debugging>

    <Exceptions Count="2">

      <Item1>

        <Name Value="ECodetoolError"/>

      </Item1>

      <Item2>

        <Name Value="EFOpenError"/>

      </Item2>

    </Exceptions>

  </Debugging>

</CONFIG>
 

------------- PascalDLLDebug.pas ------------------------
 

program CallMyLib;
 

{$APPTYPE CONSOLE}
 

uses

  Windows,

  SysUtils;
 

type

TMyProc = procedure( a : LongInt); stdcall;

var

i : Integer;

DLLHandle: THandle;

MyProc : TMyProc;

SomeHandle : Pointer;

//MyProc: procedure (X: LongInt); {$IFDEF WIN32} stdcall; {$ENDIF}

begin

DLLHandle := LoadLibrary('PascalDLLDebug.dll');

if DLLHandle >0 then

  begin

  SomeHandle := GetProcAddress(DLLHandle, 'HelloWorld');

    if Assigned(SomeHandle) then

      begin

           MyProc := TMyProc(SomeHandle);

        MyProc( 11 );

      //ShowMessage(IntToStr(i));

      end;

  end;                        //mystring

  FreeLibrary(DLLHandle);

end.

Open in new window

0
 

Author Comment

by:zordes
ID: 22675922
Hallo
I am new to expert exchange. I wanted to give to libin_v 500 points. How can I do this?
0
 
LVL 5

Expert Comment

by:libin_v
ID: 22679593
Thank You zordes, ......

If you really feel so ... here is an example http://www.experts-exchange.com/Hardware/Misc/Q_20092174.html
0
 
LVL 5

Expert Comment

by:libin_v
ID: 22681530
Hey Zordes ... I just got to know that it is not right to pass on point the way I mentioned earlier. So don't open a new question just to offer more points :)

http://www.experts-exchange.com/Other/Miscellaneous/Q_23801247.html
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now